diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap index 62d9bef5d27..e90d6303bab 100644 --- a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap @@ -338,6 +338,27 @@ return { props, get defaults() { return defaults } } })" `; +exports[`defineProps > withDefaults (locally variable) 1`] = ` +"import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from 'vue' +const defaults = { baz: false } + +export default /*#__PURE__*/_defineComponent({ + props: _mergeDefaults({ + baz: { type: Boolean, required: true } + }, defaults), + setup(__props: any, { expose: __expose }) { + __expose(); + +const props = __props; + + + +return { defaults, props } +} + +})" +`; + exports[`defineProps > withDefaults (reference) 1`] = ` "import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from 'vue' import { defaults } from './foo' diff --git a/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts index 43f54b0aa1e..4d2d417d3fb 100644 --- a/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts @@ -470,6 +470,26 @@ const props = defineProps({ foo: String }) ) }) + test('withDefaults (locally variable)', () => { + const { content } = compile(` + + `) + + assertCode(content) + expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`) + expect(content).toMatch( + ` + _mergeDefaults({ + baz: { type: Boolean, required: true } + }, defaults)`.trim() + ) + }) + // #7111 test('withDefaults (dynamic) w/ production mode', () => { const { content } = compile( @@ -607,5 +627,19 @@ const props = defineProps({ foo: String }) `) }).toThrow(`cannot accept both type and non-type arguments`) }) + + test('withDefaults (locally variable)', () => { + expect(() => { + compile(` + + `) + }).toThrow(`cannot reference locally declared variables`) + }) }) }) diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index 046797cfbe5..66acc4cbcf9 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -193,6 +193,13 @@ export function compileScript( // const ctx.bindingMetadata: BindingMetadata = {} const scriptBindings: Record = Object.create(null) const setupBindings: Record = Object.create(null) + const withDefaultsVariables: Record< + string, + { + node: Statement + needHoist?: boolean + } + > = {} let defaultExport: Node | undefined let hasAwait = false @@ -258,7 +265,11 @@ export function compileScript( if (!node) return walkIdentifiers(node, id => { const binding = setupBindings[id.name] - if (binding && binding !== BindingTypes.LITERAL_CONST) { + if ( + binding && + binding !== BindingTypes.LITERAL_CONST && + !withDefaultsVariables[id.name].needHoist + ) { ctx.error( `\`${method}()\` in