Skip to content

Commit

Permalink
feat(compiler): warn invalid children for transition and keep-alive
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Feb 6, 2020
1 parent 605cc3d commit 4cc39e1
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 2 deletions.
2 changes: 2 additions & 0 deletions packages/compiler-core/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.`,
Expand Down
11 changes: 11 additions & 0 deletions packages/compiler-core/src/transforms/transformElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion packages/compiler-dom/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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__
}

Expand All @@ -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.`
}
7 changes: 6 additions & 1 deletion packages/compiler-dom/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down
24 changes: 24 additions & 0 deletions packages/compiler-dom/src/transforms/warnTransitionChildren.ts
Original file line number Diff line number Diff line change
@@ -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: ''
})
)
}
}
}

0 comments on commit 4cc39e1

Please sign in to comment.