From d2dac0e359c47d1ed0aa77eda488e76fd6466d2d Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 29 Apr 2024 10:45:48 +0800 Subject: [PATCH] feat(compiler-sfc): enable reactive props destructure by default Also allow prohibiting usage via config. RFC: https://github.com/vuejs/rfcs/discussions/502 --- .../compileScript/defineProps.spec.ts | 18 ++++++++++++++++++ .../definePropsDestructure.spec.ts | 1 - packages/compiler-sfc/src/compileScript.ts | 7 ++++--- .../src/script/definePropsDestructure.ts | 14 ++++---------- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts index c139a3d7b..d5374ae89 100644 --- a/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts @@ -597,11 +597,29 @@ const props = defineProps({ foo: String }) foo: Foo }>() `, + { + propsDestructure: false, + }, ) expect(content).toMatch(`const { foo } = __props`) assertCode(content) }) + test('prohibiting reactive destructure', () => { + expect(() => + compile( + ``, + { + propsDestructure: 'error', + }, + ), + ).toThrow() + }) + describe('errors', () => { test('w/ both type and non-type args', () => { expect(() => { diff --git a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts index 3843ef921..20f2c432d 100644 --- a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts @@ -6,7 +6,6 @@ describe('sfc reactive props destructure', () => { function compile(src: string, options?: Partial) { return compileSFCScript(src, { inlineTemplate: true, - propsDestructure: true, ...options, }) } diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts index d4131d5c6..41f083155 100644 --- a/packages/compiler-sfc/src/compileScript.ts +++ b/packages/compiler-sfc/src/compileScript.ts @@ -106,10 +106,11 @@ export interface SFCScriptCompileOptions { */ hoistStatic?: boolean /** - * (**Experimental**) Enable reactive destructure for `defineProps` - * @default false + * Set to `false` to disable reactive destructure for `defineProps` (pre-3.5 + * behavior), or set to `'error'` to throw hard error on props destructures. + * @default true */ - propsDestructure?: boolean + propsDestructure?: boolean | 'error' /** * File system access methods to be used when resolving types * imported in SFC macros. Defaults to ts.sys in Node.js, can be overwritten diff --git a/packages/compiler-sfc/src/script/definePropsDestructure.ts b/packages/compiler-sfc/src/script/definePropsDestructure.ts index e4a59aca7..34bc7a428 100644 --- a/packages/compiler-sfc/src/script/definePropsDestructure.ts +++ b/packages/compiler-sfc/src/script/definePropsDestructure.ts @@ -22,23 +22,17 @@ import { genPropsAccessExp } from '@vue/shared' import { isCallOf, resolveObjectKey } from './utils' import type { ScriptCompileContext } from './context' import { DEFINE_PROPS } from './defineProps' -import { warnOnce } from '../warn' export function processPropsDestructure( ctx: ScriptCompileContext, declId: ObjectPattern, ) { - if (!ctx.options.propsDestructure) { + if (ctx.options.propsDestructure === 'error') { + ctx.error(`Props destructure is explicitly prohibited via config.`, declId) + } else if (ctx.options.propsDestructure === false) { return } - warnOnce( - `This project is using reactive props destructure, which is an experimental ` + - `feature. It may receive breaking changes or be removed in the future, so ` + - `use at your own risk.\n` + - `To stay updated, follow the RFC at https://github.com/vuejs/rfcs/discussions/502.`, - ) - ctx.propsDestructureDecl = declId const registerBinding = ( @@ -104,7 +98,7 @@ export function transformDestructuredProps( ctx: ScriptCompileContext, vueImportAliases: Record, ) { - if (!ctx.options.propsDestructure) { + if (ctx.options.propsDestructure === false) { return }