diff --git a/packages/uni-mp-vite/src/plugin/index.ts b/packages/uni-mp-vite/src/plugin/index.ts
index bec132b4472437d76976b332527190868fe14c79..45fe19add54e274e0db1356b40454d5005ad042b 100644
--- a/packages/uni-mp-vite/src/plugin/index.ts
+++ b/packages/uni-mp-vite/src/plugin/index.ts
@@ -12,11 +12,7 @@ import {
AppJson,
resolveVueI18nRuntime,
} from '@dcloudio/uni-cli-shared'
-import type {
- SFCDescriptor,
- SFCScriptBlock,
- SFCScriptCompileOptions,
-} from '@vue/compiler-sfc'
+
import type { CompilerOptions } from '@dcloudio/uni-mp-compiler'
import { uniOptions } from './uni'
@@ -25,6 +21,10 @@ import { createConfigResolved } from './configResolved'
import { emitFile, getFilterFiles, getTemplateFiles } from './template'
import { getNVueCssPaths } from '../plugins/pagesJson'
+import {
+ rewriteCompilerSfcParseOnce,
+ rewriteCompileScriptOnce,
+} from './polyfill'
export interface UniMiniProgramPluginOptions {
cdn?: number
@@ -107,7 +107,8 @@ export function uniMiniProgramPlugin(
let resolvedConfig: ResolvedConfig
- rewriteCompileScript()
+ rewriteCompileScriptOnce()
+ rewriteCompilerSfcParseOnce()
return {
name: 'uni:mp',
@@ -192,18 +193,3 @@ export function uniMiniProgramPlugin(
},
}
}
-
-function rewriteCompileScript() {
- const compiler = require(resolveBuiltIn('@vue/compiler-sfc'))
- const { compileScript } = compiler
- compiler.compileScript = (
- sfc: SFCDescriptor,
- options: SFCScriptCompileOptions
- ): SFCScriptBlock => {
- if (options?.templateOptions?.compilerOptions) {
- ;(options.templateOptions.compilerOptions as any).bindingCssVars =
- sfc.cssVars || []
- }
- return compileScript(sfc, options)
- }
-}
diff --git a/packages/uni-mp-vite/src/plugin/polyfill.ts b/packages/uni-mp-vite/src/plugin/polyfill.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d81227cd7e856b257809c34f6c33160a9ae598ad
--- /dev/null
+++ b/packages/uni-mp-vite/src/plugin/polyfill.ts
@@ -0,0 +1,49 @@
+import { extend } from '@vue/shared'
+import { once } from '@dcloudio/uni-shared'
+import { resolveBuiltIn } from '@dcloudio/uni-cli-shared'
+import {
+ SFCDescriptor,
+ SFCParseOptions,
+ SFCParseResult,
+ SFCScriptBlock,
+ SFCScriptCompileOptions,
+} from '@vue/compiler-sfc'
+
+export const rewriteCompileScriptOnce = once(rewriteCompileScript)
+export const rewriteCompilerSfcParseOnce = once(rewriteCompilerSfcParse)
+
+function rewriteCompileScript() {
+ const compiler = require(resolveBuiltIn('@vue/compiler-sfc'))
+ const { compileScript } = compiler
+ compiler.compileScript = (
+ sfc: SFCDescriptor,
+ options: SFCScriptCompileOptions
+ ): SFCScriptBlock => {
+ if (options?.templateOptions?.compilerOptions) {
+ ;(options.templateOptions.compilerOptions as any).bindingCssVars =
+ sfc.cssVars || []
+ }
+ return compileScript(sfc, options)
+ }
+}
+
+/**
+ * 重写 parse,解决相同内容被缓存,未触发 template 编译的问题
+ */
+function rewriteCompilerSfcParse() {
+ // @ts-ignore
+ const compilerSfc = require(resolveBuiltIn('@vue/compiler-sfc'))
+ const { parse } = compilerSfc
+ compilerSfc.parse = (
+ source: string,
+ options: SFCParseOptions
+ ): SFCParseResult => {
+ const res = parse(source, options) as SFCParseResult
+ // template 中,先hello,然后修改为,再恢复为hello,
+ // 此时因为 descriptor 被缓存,不会触发 compileTemplate,故 parse 时,每次生成一个全新的 descriptor
+ // https://github.com/vitejs/vite/blob/v2.9.13/packages/plugin-vue/src/script.ts#L44
+ // https://github.com/dcloudio/uni-app/issues/3685
+ res.descriptor = extend({}, res.descriptor)
+ return res
+ }
+}