From: Evan You Date: Mon, 16 Sep 2024 03:24:36 +0000 (+0800) Subject: fix(compiler-sfc): preserve old behavior when using withDefaults with desutructure X-Git-Tag: v3.5.6~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8492c3c49a922363d6c77ef192c133a8fbce6514;p=thirdparty%2Fvuejs%2Fcore.git fix(compiler-sfc): preserve old behavior when using withDefaults with desutructure close #11930 --- diff --git a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts index 6202f427b5..106e469f18 100644 --- a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts @@ -378,14 +378,15 @@ describe('sfc reactive props destructure', () => { ).toThrow(`destructure cannot use computed key`) }) - test('should error when used with withDefaults', () => { - expect(() => - compile( - ``, - ), - ).toThrow(`withDefaults() is unnecessary when using destructure`) + test('should warn when used with withDefaults', () => { + compile( + ``, + ) + expect( + `withDefaults() is unnecessary when using destructure`, + ).toHaveBeenWarned() }) test('should error if destructure reference local vars', () => { diff --git a/packages/compiler-sfc/src/script/context.ts b/packages/compiler-sfc/src/script/context.ts index 91ba0d7488..47b6b442a4 100644 --- a/packages/compiler-sfc/src/script/context.ts +++ b/packages/compiler-sfc/src/script/context.ts @@ -8,6 +8,7 @@ import type { ModelDecl } from './defineModel' import type { BindingMetadata } from '../../../compiler-core/src' import MagicString from 'magic-string' import type { TypeScope } from './resolveType' +import { warn } from '../warn' export class ScriptCompileContext { isJS: boolean @@ -145,20 +146,31 @@ export class ScriptCompileContext { return block.content.slice(node.start!, node.end!) } + warn(msg: string, node: Node, scope?: TypeScope): void { + warn(generateError(msg, node, this, scope)) + } + error(msg: string, node: Node, scope?: TypeScope): never { - const offset = scope ? scope.offset : this.startOffset! throw new Error( - `[@vue/compiler-sfc] ${msg}\n\n${ - (scope || this.descriptor).filename - }\n${generateCodeFrame( - (scope || this.descriptor).source, - node.start! + offset, - node.end! + offset, - )}`, + `[@vue/compiler-sfc] ${generateError(msg, node, this, scope)}`, ) } } +function generateError( + msg: string, + node: Node, + ctx: ScriptCompileContext, + scope?: TypeScope, +) { + const offset = scope ? scope.offset : ctx.startOffset! + return `${msg}\n\n${(scope || ctx.descriptor).filename}\n${generateCodeFrame( + (scope || ctx.descriptor).source, + node.start! + offset, + node.end! + offset, + )}` +} + export function resolveParserPlugins( lang: string, userPlugins?: ParserPlugin[], diff --git a/packages/compiler-sfc/src/script/defineProps.ts b/packages/compiler-sfc/src/script/defineProps.ts index 6e2032c415..9a4880a1a5 100644 --- a/packages/compiler-sfc/src/script/defineProps.ts +++ b/packages/compiler-sfc/src/script/defineProps.ts @@ -48,6 +48,7 @@ export function processDefineProps( ctx: ScriptCompileContext, node: Node, declId?: LVal, + isWithDefaults = false, ): boolean { if (!isCallOf(node, DEFINE_PROPS)) { return processWithDefaults(ctx, node, declId) @@ -81,7 +82,7 @@ export function processDefineProps( } // handle props destructure - if (declId && declId.type === 'ObjectPattern') { + if (!isWithDefaults && declId && declId.type === 'ObjectPattern') { processPropsDestructure(ctx, declId) } @@ -99,7 +100,14 @@ function processWithDefaults( if (!isCallOf(node, WITH_DEFAULTS)) { return false } - if (!processDefineProps(ctx, node.arguments[0], declId)) { + if ( + !processDefineProps( + ctx, + node.arguments[0], + declId, + true /* isWithDefaults */, + ) + ) { ctx.error( `${WITH_DEFAULTS}' first argument must be a ${DEFINE_PROPS} call.`, node.arguments[0] || node, @@ -113,10 +121,11 @@ function processWithDefaults( node, ) } - if (ctx.propsDestructureDecl) { - ctx.error( + if (declId && declId.type === 'ObjectPattern') { + ctx.warn( `${WITH_DEFAULTS}() is unnecessary when using destructure with ${DEFINE_PROPS}().\n` + - `Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(...).`, + `Reactive destructure will be disabled when using withDefaults().\n` + + `Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(...). `, node.callee, ) }