]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): preserve old behavior when using withDefaults with desutructure
authorEvan You <evan@vuejs.org>
Mon, 16 Sep 2024 03:24:36 +0000 (11:24 +0800)
committerEvan You <evan@vuejs.org>
Mon, 16 Sep 2024 03:25:04 +0000 (11:25 +0800)
close #11930

packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
packages/compiler-sfc/src/script/context.ts
packages/compiler-sfc/src/script/defineProps.ts

index 6202f427b52d2e0bba95665b3b739c92fb0e2635..106e469f1884f1421208a9c85737771b0b4f404a 100644 (file)
@@ -378,14 +378,15 @@ describe('sfc reactive props destructure', () => {
       ).toThrow(`destructure cannot use computed key`)
     })
 
-    test('should error when used with withDefaults', () => {
-      expect(() =>
-        compile(
-          `<script setup lang="ts">
-          const { foo } = withDefaults(defineProps<{ foo: string }>(), { foo: 'foo' })
-          </script>`,
-        ),
-      ).toThrow(`withDefaults() is unnecessary when using destructure`)
+    test('should warn when used with withDefaults', () => {
+      compile(
+        `<script setup lang="ts">
+        const { foo } = withDefaults(defineProps<{ foo: string }>(), { foo: 'foo' })
+        </script>`,
+      )
+      expect(
+        `withDefaults() is unnecessary when using destructure`,
+      ).toHaveBeenWarned()
     })
 
     test('should error if destructure reference local vars', () => {
index 91ba0d74884f96249f680b56aee2064f65eb7f44..47b6b442a492ce092224be86472e7952cf4035ea 100644 (file)
@@ -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[],
index 6e2032c415a77bf5a8790f3cc194eb91427778ff..9a4880a1a543f20f601b44c672df817d024aabc7 100644 (file)
@@ -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,
     )
   }