fix(compiler-core): avoid generating useless createVNode helper (#2938)

close #2739
This commit is contained in:
HcySunYang 2021-03-26 05:01:50 +08:00 committed by GitHub
parent 2451dd8ae6
commit 7715c49af9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 117 additions and 77 deletions

View File

@ -5,7 +5,7 @@ exports[`compiler: integration tests function mode 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, renderList: _renderList } = _Vue
const { toDisplayString: _toDisplayString, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, renderList: _renderList, createVNode: _createVNode } = _Vue
return (_openBlock(), _createBlock(\\"div\\", {
id: \\"foo\\",
@ -28,7 +28,7 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: integration tests function mode w/ prefixIdentifiers: true 1`] = `
"const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, renderList: _renderList } = Vue
"const { toDisplayString: _toDisplayString, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, createTextVNode: _createTextVNode, Fragment: _Fragment, renderList: _renderList, createVNode: _createVNode } = Vue
return function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"div\\", {
@ -51,7 +51,7 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: integration tests module mode 1`] = `
"import { toDisplayString as _toDisplayString, createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, createTextVNode as _createTextVNode, Fragment as _Fragment, renderList as _renderList } from \\"vue\\"
"import { toDisplayString as _toDisplayString, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, createTextVNode as _createTextVNode, Fragment as _Fragment, renderList as _renderList, createVNode as _createVNode } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"div\\", {

View File

@ -239,7 +239,7 @@ exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist expr
return function render(_ctx, _cache) {
with (_ctx) {
const { toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { toDisplayString: _toDisplayString, createTextVNode: _createTextVNode, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
@ -276,7 +276,7 @@ exports[`compiler: hoistStatic transform prefixIdentifiers should NOT hoist keye
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
@ -308,7 +308,7 @@ exports[`compiler: hoistStatic transform should NOT hoist element with dynamic k
return function render(_ctx, _cache) {
with (_ctx) {
const { openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
(_openBlock(), _createBlock(\\"div\\", { key: foo }))
@ -350,7 +350,7 @@ exports[`compiler: hoistStatic transform should NOT hoist root node 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\"))
}

View File

@ -7,7 +7,7 @@ exports[`compiler: expression transform bindingMetadata inline mode 1`] = `
`;
exports[`compiler: expression transform bindingMetadata non-inline mode 1`] = `
"const { toDisplayString: _toDisplayString, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { toDisplayString: _toDisplayString, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock(\\"div\\", null, _toDisplayString($props.props) + \\" \\" + _toDisplayString($setup.setup) + \\" \\" + _toDisplayString($data.data) + \\" \\" + _toDisplayString($options.options), 1 /* TEXT */))

View File

@ -5,7 +5,7 @@ exports[`compiler: v-for codegen basic v-for 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(\\"span\\"))
@ -50,7 +50,7 @@ exports[`compiler: v-for codegen skipped key 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item, __, index) => {
return (_openBlock(), _createBlock(\\"span\\"))
@ -64,7 +64,7 @@ exports[`compiler: v-for codegen skipped value & key 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (_, __, index) => {
return (_openBlock(), _createBlock(\\"span\\"))
@ -78,7 +78,7 @@ exports[`compiler: v-for codegen skipped value 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (_, key, index) => {
return (_openBlock(), _createBlock(\\"span\\"))
@ -109,7 +109,7 @@ exports[`compiler: v-for codegen template v-for key injection with single child
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item) => {
return (_openBlock(), _createBlock(\\"span\\", {
@ -154,7 +154,7 @@ exports[`compiler: v-for codegen v-for on element with custom directive 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, resolveDirective: _resolveDirective, createVNode: _createVNode, withDirectives: _withDirectives } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, resolveDirective: _resolveDirective, withDirectives: _withDirectives } = _Vue
const _directive_foo = _resolveDirective(\\"foo\\")
@ -186,7 +186,7 @@ exports[`compiler: v-for codegen v-if + v-for 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode, createCommentVNode: _createCommentVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(true), _createBlock(_Fragment, { key: 0 }, _renderList(list, (i) => {
@ -218,7 +218,7 @@ exports[`compiler: v-for codegen value + key + index 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode } = _Vue
const { renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(true), _createBlock(_Fragment, null, _renderList(items, (item, key, index) => {
return (_openBlock(), _createBlock(\\"span\\"))

View File

@ -5,7 +5,7 @@ exports[`compiler: v-if codegen basic v-if 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
@ -19,7 +19,7 @@ exports[`compiler: v-if codegen increasing key: v-if + v-else-if + v-else 1`] =
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [
ok
@ -40,7 +40,7 @@ exports[`compiler: v-if codegen multiple v-if that are sibling nodes should have
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [
ok
@ -91,7 +91,7 @@ exports[`compiler: v-if codegen v-if + v-else 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
@ -105,7 +105,7 @@ exports[`compiler: v-if codegen v-if + v-else-if + v-else 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue
return ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))
@ -121,7 +121,7 @@ exports[`compiler: v-if codegen v-if + v-else-if 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue
return ok
? (_openBlock(), _createBlock(\\"div\\", { key: 0 }))

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: transform v-model compound expression (with prefixIdentifiers) 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"input\\", {
@ -16,7 +16,7 @@ exports[`compiler: transform v-model compound expression 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", {
modelValue: model[index],
@ -31,7 +31,7 @@ exports[`compiler: transform v-model simple expression (with multilines) 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", {
modelValue:
@ -50,7 +50,7 @@ foo
`;
exports[`compiler: transform v-model simple expression (with prefixIdentifiers) 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"input\\", {
@ -65,7 +65,7 @@ exports[`compiler: transform v-model simple expression 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", {
modelValue: model,
@ -80,7 +80,7 @@ exports[`compiler: transform v-model with argument 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", {
value: model,
@ -91,7 +91,7 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: transform v-model with dynamic argument (with prefixIdentifiers) 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"input\\", {
@ -106,7 +106,7 @@ exports[`compiler: transform v-model with dynamic argument 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"input\\", {
[value]: model,

View File

@ -62,7 +62,7 @@ exports[`compiler: v-once transform on slot outlet 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { setBlockTracking: _setBlockTracking, renderSlot: _renderSlot, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { setBlockTracking: _setBlockTracking, renderSlot: _renderSlot, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return (_openBlock(), _createBlock(\\"div\\", null, [
_cache[1] || (

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: transform component slots dynamically named slots 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\")
@ -30,7 +30,7 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: transform component slots named slot with v-for w/ prefixIdentifiers: true 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\")
@ -47,7 +47,7 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: transform component slots named slot with v-if + prefixIdentifiers: true 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\")
@ -68,7 +68,7 @@ exports[`compiler: transform component slots named slot with v-if + v-else-if +
return function render(_ctx, _cache) {
with (_ctx) {
const { resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
@ -97,7 +97,7 @@ exports[`compiler: transform component slots named slot with v-if 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { resolveComponent: _resolveComponent, withCtx: _withCtx, createSlots: _createSlots, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _component_Comp = _resolveComponent(\\"Comp\\")
@ -158,7 +158,7 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: transform component slots on component dynamically named slot 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\")
@ -171,7 +171,7 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: transform component slots on component named slot 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\")
@ -184,7 +184,7 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: transform component slots on-component default slot 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\")
@ -197,7 +197,7 @@ return function render(_ctx, _cache) {
`;
exports[`compiler: transform component slots template named slots 1`] = `
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, createVNode: _createVNode, openBlock: _openBlock, createBlock: _createBlock } = Vue
"const { toDisplayString: _toDisplayString, resolveComponent: _resolveComponent, withCtx: _withCtx, openBlock: _openBlock, createBlock: _createBlock } = Vue
return function render(_ctx, _cache) {
const _component_Comp = _resolveComponent(\\"Comp\\")

View File

@ -35,7 +35,8 @@ import {
helperNameMap,
CREATE_BLOCK,
CREATE_COMMENT,
OPEN_BLOCK
OPEN_BLOCK,
CREATE_VNODE
} from './runtimeHelpers'
import { isVSlot } from './utils'
import { hoistStatic, isSingleElementRoot } from './transforms/hoistStatic'
@ -85,7 +86,7 @@ export interface TransformContext
extends Required<Omit<TransformOptions, 'filename'>> {
selfName: string | null
root: RootNode
helpers: Set<symbol>
helpers: Map<symbol, number>
components: Set<string>
directives: Set<string>
hoists: (JSChildNode | null)[]
@ -103,6 +104,7 @@ export interface TransformContext
childIndex: number
currentNode: RootNode | TemplateChildNode | null
helper<T extends symbol>(name: T): T
removeHelper<T extends symbol>(name: T): void
helperString(name: symbol): string
replaceNode(node: TemplateChildNode): void
removeNode(node?: TemplateChildNode): void
@ -161,7 +163,7 @@ export function createTransformContext(
// state
root,
helpers: new Set(),
helpers: new Map(),
components: new Set(),
directives: new Set(),
hoists: [],
@ -182,9 +184,21 @@ export function createTransformContext(
// methods
helper(name) {
context.helpers.add(name)
const count = context.helpers.get(name) || 0
context.helpers.set(name, count + 1)
return name
},
removeHelper(name) {
const count = context.helpers.get(name)
if (count) {
const currentCount = count - 1
if (!currentCount) {
context.helpers.delete(name)
} else {
context.helpers.set(name, currentCount)
}
}
},
helperString(name) {
return `_${helperNameMap[context.helper(name)]}`
},
@ -292,7 +306,7 @@ export function transform(root: RootNode, options: TransformOptions) {
createRootCodegen(root, context)
}
// finalize meta information
root.helpers = [...context.helpers]
root.helpers = [...context.helpers.keys()]
root.components = [...context.components]
root.directives = [...context.directives]
root.imports = context.imports
@ -302,7 +316,7 @@ export function transform(root: RootNode, options: TransformOptions) {
}
function createRootCodegen(root: RootNode, context: TransformContext) {
const { helper } = context
const { helper, removeHelper } = context
const { children } = root
if (children.length === 1) {
const child = children[0]
@ -312,9 +326,12 @@ function createRootCodegen(root: RootNode, context: TransformContext) {
// SimpleExpressionNode
const codegenNode = child.codegenNode
if (codegenNode.type === NodeTypes.VNODE_CALL) {
codegenNode.isBlock = true
helper(OPEN_BLOCK)
helper(CREATE_BLOCK)
if (!codegenNode.isBlock) {
removeHelper(CREATE_VNODE)
codegenNode.isBlock = true
helper(OPEN_BLOCK)
helper(CREATE_BLOCK)
}
}
root.codegenNode = codegenNode
} else {

View File

@ -14,7 +14,7 @@ import {
import { TransformContext } from '../transform'
import { PatchFlags, isString, isSymbol } from '@vue/shared'
import { isSlotOutlet } from '../utils'
import { CREATE_VNODE } from '../runtimeHelpers'
import { CREATE_BLOCK, CREATE_VNODE, OPEN_BLOCK } from '../runtimeHelpers'
export function hoistStatic(root: RootNode, context: TransformContext) {
walk(
@ -212,6 +212,8 @@ export function getConstantType(
// static then they don't need to be blocks since there will be no
// nested updates.
if (codegenNode.isBlock) {
context.removeHelper(OPEN_BLOCK)
context.removeHelper(CREATE_BLOCK)
codegenNode.isBlock = false
context.helper(CREATE_VNODE)
}

View File

@ -48,7 +48,7 @@ import { PatchFlags, PatchFlagNames } from '@vue/shared'
export const transformFor = createStructuralDirectiveTransform(
'for',
(node, dir, context) => {
const { helper } = context
const { helper, removeHelper } = context
return processFor(node, dir, context, forNode => {
// create the loop render function expression now, and add the
// iterator on exit after all children have been traversed
@ -166,6 +166,16 @@ export const transformFor = createStructuralDirectiveTransform(
if (isTemplate && keyProperty) {
injectProp(childBlock, keyProperty, context)
}
if (childBlock.isBlock !== !isStableFragment) {
if (childBlock.isBlock) {
// switch from block to vnode
removeHelper(OPEN_BLOCK)
removeHelper(CREATE_BLOCK)
} else {
// switch from vnode to block
removeHelper(CREATE_VNODE)
}
}
childBlock.isBlock = !isStableFragment
if (childBlock.isBlock) {
helper(OPEN_BLOCK)

View File

@ -31,7 +31,8 @@ import {
CREATE_BLOCK,
FRAGMENT,
CREATE_COMMENT,
OPEN_BLOCK
OPEN_BLOCK,
CREATE_VNODE
} from '../runtimeHelpers'
import { injectProp, findDir, findProp } from '../utils'
import { PatchFlags, PatchFlagNames } from '@vue/shared'
@ -225,7 +226,7 @@ function createChildrenCodegenNode(
keyIndex: number,
context: TransformContext
): BlockCodegenNode {
const { helper } = context
const { helper, removeHelper } = context
const keyProperty = createObjectProperty(
`key`,
createSimpleExpression(
@ -275,7 +276,8 @@ function createChildrenCodegenNode(
const vnodeCall = (firstChild as ElementNode)
.codegenNode as BlockCodegenNode
// Change createVNode to createBlock.
if (vnodeCall.type === NodeTypes.VNODE_CALL) {
if (vnodeCall.type === NodeTypes.VNODE_CALL && !vnodeCall.isBlock) {
removeHelper(CREATE_VNODE)
vnodeCall.isBlock = true
helper(OPEN_BLOCK)
helper(CREATE_BLOCK)

View File

@ -5,7 +5,7 @@ exports[`compiler: transform v-model errors should allow usage on custom element
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelText: _vModelText, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"my-input\\", {
\\"onUpdate:modelValue\\": $event => (model = $event)
@ -21,7 +21,7 @@ exports[`compiler: transform v-model input w/ dynamic v-bind 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelDynamic: _vModelDynamic, mergeProps: _mergeProps, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelDynamic: _vModelDynamic, mergeProps: _mergeProps, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"input\\", _mergeProps(obj, {
\\"onUpdate:modelValue\\": $event => (model = $event)
@ -37,7 +37,7 @@ exports[`compiler: transform v-model input w/ dynamic v-bind 2`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelDynamic: _vModelDynamic, resolveDirective: _resolveDirective, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelDynamic: _vModelDynamic, resolveDirective: _resolveDirective, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _directive_bind = _resolveDirective(\\"bind\\")
@ -56,7 +56,7 @@ exports[`compiler: transform v-model modifiers .lazy 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelText: _vModelText, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
\\"onUpdate:modelValue\\": $event => (model = $event)
@ -77,7 +77,7 @@ exports[`compiler: transform v-model modifiers .number 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelText: _vModelText, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
\\"onUpdate:modelValue\\": $event => (model = $event)
@ -98,7 +98,7 @@ exports[`compiler: transform v-model modifiers .trim 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelText: _vModelText, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
\\"onUpdate:modelValue\\": $event => (model = $event)
@ -119,7 +119,7 @@ exports[`compiler: transform v-model simple expression 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelText: _vModelText, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
\\"onUpdate:modelValue\\": $event => (model = $event)
@ -135,7 +135,7 @@ exports[`compiler: transform v-model simple expression for input (checkbox) 1`]
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelCheckbox: _vModelCheckbox, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelCheckbox: _vModelCheckbox, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
type: \\"checkbox\\",
@ -152,7 +152,7 @@ exports[`compiler: transform v-model simple expression for input (dynamic type)
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelDynamic: _vModelDynamic, resolveDirective: _resolveDirective, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelDynamic: _vModelDynamic, resolveDirective: _resolveDirective, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const _directive_bind = _resolveDirective(\\"bind\\")
@ -171,7 +171,7 @@ exports[`compiler: transform v-model simple expression for input (radio) 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelRadio: _vModelRadio, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelRadio: _vModelRadio, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
type: \\"radio\\",
@ -188,7 +188,7 @@ exports[`compiler: transform v-model simple expression for input (text) 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelText: _vModelText, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"input\\", {
type: \\"text\\",
@ -205,7 +205,7 @@ exports[`compiler: transform v-model simple expression for select 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelSelect: _vModelSelect, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelSelect: _vModelSelect, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"select\\", {
\\"onUpdate:modelValue\\": $event => (model = $event)
@ -221,7 +221,7 @@ exports[`compiler: transform v-model simple expression for textarea 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vModelText: _vModelText, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vModelText: _vModelText, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"textarea\\", {
\\"onUpdate:modelValue\\": $event => (model = $event)

View File

@ -5,7 +5,7 @@ exports[`compiler: v-show transform simple expression 1`] = `
return function render(_ctx, _cache) {
with (_ctx) {
const { vShow: _vShow, createVNode: _createVNode, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
const { vShow: _vShow, withDirectives: _withDirectives, openBlock: _openBlock, createBlock: _createBlock } = _Vue
return _withDirectives((_openBlock(), _createBlock(\\"div\\", null, null, 512 /* NEED_PATCH */)), [
[_vShow, a]

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler sfc: transform asset url should allow for full base URLs, with paths 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"img\\", { src: \\"http://localhost:3000/src/logo.png\\" }))
@ -9,7 +9,7 @@ export function render(_ctx, _cache) {
`;
exports[`compiler sfc: transform asset url should allow for full base URLs, without paths 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"img\\", { src: \\"http://localhost:3000/logo.png\\" }))
@ -17,7 +17,7 @@ export function render(_ctx, _cache) {
`;
exports[`compiler sfc: transform asset url should allow for full base URLs, without port 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"img\\", { src: \\"http://localhost/logo.png\\" }))
@ -25,7 +25,7 @@ export function render(_ctx, _cache) {
`;
exports[`compiler sfc: transform asset url should allow for full base URLs, without protocol 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"img\\", { src: \\"//localhost/logo.png\\" }))
@ -33,7 +33,7 @@ export function render(_ctx, _cache) {
`;
exports[`compiler sfc: transform asset url support uri fragment 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
import _imports_0 from '@svg/file.svg'
@ -45,7 +45,7 @@ export function render(_ctx, _cache) {
`;
exports[`compiler sfc: transform asset url support uri is empty 1`] = `
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
"import { openBlock as _openBlock, createBlock as _createBlock } from \\"vue\\"
export function render(_ctx, _cache) {
return (_openBlock(), _createBlock(\\"use\\", { href: '' }))

View File

@ -207,7 +207,7 @@ describe('ssr: components', () => {
</template>
</foo>`).code
).toMatchInlineSnapshot(`
"const { resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createVNode: _createVNode, createCommentVNode: _createCommentVNode } = require(\\"vue\\")
"const { resolveComponent: _resolveComponent, withCtx: _withCtx, renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = require(\\"vue\\")
const { ssrRenderComponent: _ssrRenderComponent, ssrRenderList: _ssrRenderList } = require(\\"@vue/server-renderer\\")
return function ssrRender(_ctx, _push, _parent, _attrs) {

View File

@ -298,8 +298,17 @@ function subTransform(
traverseNode(childRoot, childContext)
// merge helpers/components/directives into parent context
;(['helpers', 'components', 'directives'] as const).forEach(key => {
childContext[key].forEach((value: any) => {
;(parentContext[key] as any).add(value)
childContext[key].forEach((value: any, helperKey: any) => {
if (key === 'helpers') {
const parentCount = parentContext.helpers.get(helperKey)
if (parentCount === undefined) {
parentContext.helpers.set(helperKey, value)
} else {
parentContext.helpers.set(helperKey, value + parentCount)
}
} else {
;(parentContext[key] as any).add(value)
}
})
})
// imports/hoists are not merged because: