diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap
index 9f2183ce8..3855360c4 100644
--- a/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap
+++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.spec.ts.snap
@@ -280,6 +280,18 @@ export function render(_ctx) {
}"
`;
+exports[`compile > helper alias > should avoid conflicts with existing variable names 1`] = `
+"import { child as _child2, toDisplayString as _toDisplayString, setText as _setText, renderEffect as _renderEffect, template as _template } from 'vue';
+const t0 = _template("
", true)
+
+export function render(_ctx, $props, $emit, $attrs, $slots) {
+ const n0 = t0()
+ const x0 = _child2(n0)
+ _renderEffect(() => _setText(x0, _toDisplayString(_ctx.foo)))
+ return n0
+}"
+`;
+
exports[`compile > setInsertionState > next, child and nthChild should be above the setInsertionState 1`] = `
"import { resolveComponent as _resolveComponent, child as _child, next as _next, setInsertionState as _setInsertionState, createComponentWithFallback as _createComponentWithFallback, nthChild as _nthChild, createIf as _createIf, setProp as _setProp, renderEffect as _renderEffect, template as _template } from 'vue';
const t0 = _template("")
diff --git a/packages/compiler-vapor/__tests__/compile.spec.ts b/packages/compiler-vapor/__tests__/compile.spec.ts
index 7963a9e98..19bb45b48 100644
--- a/packages/compiler-vapor/__tests__/compile.spec.ts
+++ b/packages/compiler-vapor/__tests__/compile.spec.ts
@@ -268,4 +268,18 @@ describe('compile', () => {
expect(code).matchSnapshot()
})
})
+
+ describe('helper alias', () => {
+ test('should avoid conflicts with existing variable names', () => {
+ const code = compile(`{{ foo }}
`, {
+ bindingMetadata: {
+ _child: BindingTypes.LITERAL_CONST,
+ _child1: BindingTypes.SETUP_REF,
+ },
+ })
+ expect(code).matchSnapshot()
+ expect(code).contains('child as _child2')
+ expect(code).contains('const x0 = _child2(n0)')
+ })
+ })
})
diff --git a/packages/compiler-vapor/src/generate.ts b/packages/compiler-vapor/src/generate.ts
index 193a0f5da..ca26138c8 100644
--- a/packages/compiler-vapor/src/generate.ts
+++ b/packages/compiler-vapor/src/generate.ts
@@ -24,11 +24,31 @@ export type CodegenOptions = Omit
export class CodegenContext {
options: Required
- helpers: Set = new Set([])
+ bindingNames: Set = new Set()
- helper = (name: CoreHelper | VaporHelper) => {
- this.helpers.add(name)
- return `_${name}`
+ helpers: Map = new Map()
+
+ helper = (name: CoreHelper | VaporHelper): string => {
+ if (this.helpers.has(name)) {
+ return this.helpers.get(name)!
+ }
+
+ const base = `_${name}`
+ if (this.bindingNames.size === 0) {
+ this.helpers.set(name, base)
+ return base
+ }
+
+ // check whether an alias is already used bindings
+ let alias = base
+ let i = 0
+ while (this.bindingNames.has(alias)) {
+ i++
+ alias = `${base}${i}`
+ }
+
+ this.helpers.set(name, alias)
+ return alias
}
delegates: Set = new Set()
@@ -90,6 +110,11 @@ export class CodegenContext {
}
this.options = extend(defaultOptions, options)
this.block = ir.block
+ this.bindingNames = new Set(
+ this.options.bindingMetadata
+ ? Object.keys(this.options.bindingMetadata)
+ : [],
+ )
}
}
@@ -105,7 +130,6 @@ export function generate(
): VaporCodegenResult {
const [frag, push] = buildCodeFragment()
const context = new CodegenContext(ir, options)
- const { helpers } = context
const { inline, bindingMetadata } = options
const functionName = 'render'
@@ -156,7 +180,7 @@ export function generate(
ast: ir,
preamble,
map: map && map.toJSON(),
- helpers,
+ helpers: new Set(Array.from(context.helpers.keys())),
}
}
@@ -169,11 +193,11 @@ function genDelegates({ delegates, helper }: CodegenContext) {
: ''
}
-function genHelperImports({ helpers, helper, options }: CodegenContext) {
+function genHelperImports({ helpers, options }: CodegenContext) {
let imports = ''
if (helpers.size) {
- imports += `import { ${[...helpers]
- .map(h => `${h} as _${h}`)
+ imports += `import { ${Array.from(helpers)
+ .map(([h, alias]) => `${h} as ${alias}`)
.join(', ')} } from '${options.runtimeModuleName}';\n`
}
return imports