fix(frontend): lazy-load Stripe payment dependency
This commit is contained in:
@@ -111,7 +111,7 @@ let elementsInstance: StripeElements | null = null
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const { loadStripe } = await import('@stripe/stripe-js')
|
||||
const { loadStripe } = await import('@stripe/stripe-js/pure')
|
||||
const stripe = await loadStripe(props.publishableKey)
|
||||
if (!stripe) { initError.value = t('payment.stripeLoadFailed'); return }
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ onMounted(async () => {
|
||||
const publishableKey = paymentStore.config?.stripe_publishable_key
|
||||
if (!publishableKey) { initError.value = t('payment.stripeNotConfigured'); return }
|
||||
|
||||
const { loadStripe } = await import('@stripe/stripe-js')
|
||||
const { loadStripe } = await import('@stripe/stripe-js/pure')
|
||||
const stripe = await loadStripe(publishableKey)
|
||||
if (!stripe) { initError.value = t('payment.stripeLoadFailed'); return }
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ async function initStripe(clientSecret: string, publishableKey: string) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
const { loadStripe } = await import('@stripe/stripe-js')
|
||||
const { loadStripe } = await import('@stripe/stripe-js/pure')
|
||||
const stripe = await loadStripe(publishableKey)
|
||||
if (!stripe) { error.value = t('payment.stripeLoadFailed'); return }
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ vi.mock('@/api/payment', () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@stripe/stripe-js', () => ({
|
||||
vi.mock('@stripe/stripe-js/pure', () => ({
|
||||
loadStripe,
|
||||
}))
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
const frontendRoot = resolve(__dirname, '../../../..')
|
||||
const stripeConsumers = [
|
||||
'src/views/user/StripePaymentView.vue',
|
||||
'src/views/user/StripePopupView.vue',
|
||||
'src/components/payment/StripePaymentInline.vue',
|
||||
]
|
||||
|
||||
function readFrontendFile(path: string): string {
|
||||
return readFileSync(resolve(frontendRoot, path), 'utf8')
|
||||
}
|
||||
|
||||
describe('Stripe lazy-loading contract', () => {
|
||||
it.each(stripeConsumers)('%s uses the side-effect-free Stripe loader', (path) => {
|
||||
const source = readFrontendFile(path)
|
||||
|
||||
expect(source).toContain("await import('@stripe/stripe-js/pure')")
|
||||
expect(source).not.toMatch(/await import\(['"]@stripe\/stripe-js['"]\)/)
|
||||
})
|
||||
|
||||
it('keeps Stripe out of the shared vendor chunk', () => {
|
||||
const viteConfig = readFrontendFile('vite.config.ts')
|
||||
const stripeRule = viteConfig.indexOf("id.includes('/@stripe/stripe-js/')")
|
||||
const miscFallback = viteConfig.indexOf("return 'vendor-misc'")
|
||||
|
||||
expect(stripeRule).toBeGreaterThan(-1)
|
||||
expect(viteConfig.slice(stripeRule, miscFallback)).toContain("return 'vendor-stripe'")
|
||||
expect(stripeRule).toBeLessThan(miscFallback)
|
||||
})
|
||||
})
|
||||
@@ -96,6 +96,11 @@ export default defineConfig(({ mode }) => {
|
||||
return 'vendor-i18n'
|
||||
}
|
||||
|
||||
// Stripe 仅在支付流程中按需加载,避免进入首页公共依赖。
|
||||
if (id.includes('/@stripe/stripe-js/')) {
|
||||
return 'vendor-stripe'
|
||||
}
|
||||
|
||||
// 其他小型第三方库合并
|
||||
return 'vendor-misc'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user