]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler): warn invalid children for transition and keep-alive
authorEvan You <yyx990803@gmail.com>
Thu, 6 Feb 2020 20:53:26 +0000 (15:53 -0500)
committerEvan You <yyx990803@gmail.com>
Thu, 6 Feb 2020 22:45:46 +0000 (17:45 -0500)
packages/compiler-core/src/errors.ts
packages/compiler-core/src/transforms/transformElement.ts
packages/compiler-dom/src/errors.ts
packages/compiler-dom/src/index.ts
packages/compiler-dom/src/transforms/warnTransitionChildren.ts [new file with mode: 0644]

index e2fe090a050787b4c0d2713cea1c84d1ca546783..a46fa80e9118c77e4507fdd662a3997aab603b6c 100644 (file)
@@ -81,6 +81,7 @@ export const enum ErrorCodes {
   X_V_MODEL_MALFORMED_EXPRESSION,
   X_V_MODEL_ON_SCOPE_VARIABLE,
   X_INVALID_EXPRESSION,
+  X_KEEP_ALIVE_INVALID_CHILDREN,
 
   // generic errors
   X_PREFIX_ID_NOT_SUPPORTED,
@@ -174,6 +175,7 @@ export const errorMessages: { [code: number]: string } = {
   [ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION]: `v-model value must be a valid JavaScript member expression.`,
   [ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
   [ErrorCodes.X_INVALID_EXPRESSION]: `Invalid JavaScript expression.`,
+  [ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: `<KeepAlive> expects exactly one child component.`,
 
   // generic errors
   [ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
index 7c9dd0fe8fd1399f7e06d7aad80a2b531be52ace..1d685dce59b5ad648e235e93378f2f1859e650d2 100644 (file)
@@ -100,6 +100,17 @@ export const transformElement: NodeTransform = (node, context) => {
       if (!hasProps) {
         args.push(`null`)
       }
+
+      if (__DEV__ && nodeType === KEEP_ALIVE && node.children.length > 1) {
+        context.onError(
+          createCompilerError(ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN, {
+            start: node.children[0].loc.start,
+            end: node.children[node.children.length - 1].loc.end,
+            source: ''
+          })
+        )
+      }
+
       // Portal & KeepAlive should have normal children instead of slots
       // Portal is not a real component has dedicated handling in the renderer
       // KeepAlive should not track its own deps so that it can be used inside
index 8ead25260424d05a652972cfb1c7feec55975169..1519324df29ee81fdadb023026ece82c5182e93b 100644 (file)
@@ -30,6 +30,7 @@ export const enum DOMErrorCodes {
   X_V_MODEL_ON_FILE_INPUT_ELEMENT,
   X_V_MODEL_UNNECESSARY_VALUE,
   X_V_SHOW_NO_EXPRESSION,
+  X_TRANSITION_INVALID_CHILDREN,
   __EXTEND_POINT__
 }
 
@@ -42,5 +43,6 @@ export const DOMErrorMessages: { [code: number]: string } = {
   [DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT]: `v-model argument is not supported on plain elements.`,
   [DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT]: `v-model cannot used on file inputs since they are read-only. Use a v-on:change listener instead.`,
   [DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE]: `Unnecessary value binding used alongside v-model. It will interfere with v-model's behavior.`,
-  [DOMErrorCodes.X_V_SHOW_NO_EXPRESSION]: `v-show is missing expression.`
+  [DOMErrorCodes.X_V_SHOW_NO_EXPRESSION]: `v-show is missing expression.`,
+  [DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN]: `<Transition> expects exactly one child element or component.`
 }
index 5e1d17dfd23ddbf83f209fdb4ef31bbd85776e5f..674a3ef8350c24d7c9040f63eca4d20ecfd93222 100644 (file)
@@ -17,6 +17,7 @@ import { transformModel } from './transforms/vModel'
 import { transformOn } from './transforms/vOn'
 import { transformShow } from './transforms/vShow'
 import { TRANSITION, TRANSITION_GROUP } from './runtimeHelpers'
+import { warnTransitionChildren } from './transforms/warnTransitionChildren'
 
 export const parserOptions = __BROWSER__
   ? parserOptionsMinimal
@@ -37,7 +38,11 @@ export function compile(
   return baseCompile(template, {
     ...parserOptions,
     ...options,
-    nodeTransforms: [transformStyle, ...(options.nodeTransforms || [])],
+    nodeTransforms: [
+      transformStyle,
+      ...(__DEV__ ? [warnTransitionChildren] : []),
+      ...(options.nodeTransforms || [])
+    ],
     directiveTransforms: {
       cloak: noopDirectiveTransform,
       html: transformVHtml,
diff --git a/packages/compiler-dom/src/transforms/warnTransitionChildren.ts b/packages/compiler-dom/src/transforms/warnTransitionChildren.ts
new file mode 100644 (file)
index 0000000..0cd1d66
--- /dev/null
@@ -0,0 +1,24 @@
+import { NodeTransform, NodeTypes, ElementTypes } from '@vue/compiler-core'
+import { TRANSITION } from '../runtimeHelpers'
+import { createDOMCompilerError, DOMErrorCodes } from '../errors'
+
+export const warnTransitionChildren: NodeTransform = (node, context) => {
+  if (
+    node.type === NodeTypes.ELEMENT &&
+    node.tagType === ElementTypes.COMPONENT
+  ) {
+    const component = context.isBuiltInComponent(node.tag)
+    if (
+      component === TRANSITION &&
+      (node.children.length > 1 || node.children[0].type === NodeTypes.FOR)
+    ) {
+      context.onError(
+        createDOMCompilerError(DOMErrorCodes.X_TRANSITION_INVALID_CHILDREN, {
+          start: node.children[0].loc.start,
+          end: node.children[node.children.length - 1].loc.end,
+          source: ''
+        })
+      )
+    }
+  }
+}