fix(compiler-core): hoisted vnode calls and scoped id calls should be marked pure
Otherwise they cannot be tree-shaken
This commit is contained in:
parent
6c60ce13e0
commit
cad25d95a3
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
exports[`scopeId compiler support should push scopeId for hoisted nodes 1`] = `
|
exports[`scopeId compiler support should push scopeId for hoisted nodes 1`] = `
|
||||||
"import { createVNode as _createVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \\"vue\\"
|
"import { createVNode as _createVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId, pushScopeId as _pushScopeId, popScopeId as _popScopeId } from \\"vue\\"
|
||||||
const _withId = _withScopeId(\\"test\\")
|
const _withId = /*#__PURE__*/ _withScopeId(\\"test\\")
|
||||||
|
|
||||||
_pushScopeId(\\"test\\")
|
_pushScopeId(\\"test\\")
|
||||||
const _hoisted_1 = _createVNode(\\"div\\", null, \\"hello\\", -1 /* HOISTED */)
|
const _hoisted_1 = /*#__PURE__*/ _createVNode(\\"div\\", null, \\"hello\\", -1 /* HOISTED */)
|
||||||
const _hoisted_2 = _createVNode(\\"div\\", null, \\"world\\", -1 /* HOISTED */)
|
const _hoisted_2 = /*#__PURE__*/ _createVNode(\\"div\\", null, \\"world\\", -1 /* HOISTED */)
|
||||||
_popScopeId()
|
_popScopeId()
|
||||||
|
|
||||||
export const render = _withId(function render(_ctx, _cache) {
|
export const render = /*#__PURE__*/ _withId(function render(_ctx, _cache) {
|
||||||
return (_openBlock(), _createBlock(\\"div\\", null, [
|
return (_openBlock(), _createBlock(\\"div\\", null, [
|
||||||
_hoisted_1,
|
_hoisted_1,
|
||||||
_createTextVNode(_toDisplayString(_ctx.foo), 1 /* TEXT */),
|
_createTextVNode(_toDisplayString(_ctx.foo), 1 /* TEXT */),
|
||||||
@ -20,9 +20,9 @@ export const render = _withId(function render(_ctx, _cache) {
|
|||||||
|
|
||||||
exports[`scopeId compiler support should wrap default slot 1`] = `
|
exports[`scopeId compiler support should wrap default slot 1`] = `
|
||||||
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
|
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
|
||||||
const _withId = _withScopeId(\\"test\\")
|
const _withId = /*#__PURE__*/ _withScopeId(\\"test\\")
|
||||||
|
|
||||||
export const render = _withId(function render(_ctx, _cache) {
|
export const render = /*#__PURE__*/ _withId(function render(_ctx, _cache) {
|
||||||
const _component_Child = _resolveComponent(\\"Child\\")
|
const _component_Child = _resolveComponent(\\"Child\\")
|
||||||
|
|
||||||
return (_openBlock(), _createBlock(_component_Child, null, {
|
return (_openBlock(), _createBlock(_component_Child, null, {
|
||||||
@ -36,9 +36,9 @@ export const render = _withId(function render(_ctx, _cache) {
|
|||||||
|
|
||||||
exports[`scopeId compiler support should wrap dynamic slots 1`] = `
|
exports[`scopeId compiler support should wrap dynamic slots 1`] = `
|
||||||
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, renderList as _renderList, createSlots as _createSlots, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
|
"import { createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, renderList as _renderList, createSlots as _createSlots, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
|
||||||
const _withId = _withScopeId(\\"test\\")
|
const _withId = /*#__PURE__*/ _withScopeId(\\"test\\")
|
||||||
|
|
||||||
export const render = _withId(function render(_ctx, _cache) {
|
export const render = /*#__PURE__*/ _withId(function render(_ctx, _cache) {
|
||||||
const _component_Child = _resolveComponent(\\"Child\\")
|
const _component_Child = _resolveComponent(\\"Child\\")
|
||||||
|
|
||||||
return (_openBlock(), _createBlock(_component_Child, null, _createSlots({ _: 1 }, [
|
return (_openBlock(), _createBlock(_component_Child, null, _createSlots({ _: 1 }, [
|
||||||
@ -64,9 +64,9 @@ export const render = _withId(function render(_ctx, _cache) {
|
|||||||
|
|
||||||
exports[`scopeId compiler support should wrap named slots 1`] = `
|
exports[`scopeId compiler support should wrap named slots 1`] = `
|
||||||
"import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
|
"import { toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createVNode as _createVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
|
||||||
const _withId = _withScopeId(\\"test\\")
|
const _withId = /*#__PURE__*/ _withScopeId(\\"test\\")
|
||||||
|
|
||||||
export const render = _withId(function render(_ctx, _cache) {
|
export const render = /*#__PURE__*/ _withId(function render(_ctx, _cache) {
|
||||||
const _component_Child = _resolveComponent(\\"Child\\")
|
const _component_Child = _resolveComponent(\\"Child\\")
|
||||||
|
|
||||||
return (_openBlock(), _createBlock(_component_Child, null, {
|
return (_openBlock(), _createBlock(_component_Child, null, {
|
||||||
@ -83,9 +83,9 @@ export const render = _withId(function render(_ctx, _cache) {
|
|||||||
|
|
||||||
exports[`scopeId compiler support should wrap render function 1`] = `
|
exports[`scopeId compiler support should wrap render function 1`] = `
|
||||||
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
|
"import { createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock, withScopeId as _withScopeId } from \\"vue\\"
|
||||||
const _withId = _withScopeId(\\"test\\")
|
const _withId = /*#__PURE__*/ _withScopeId(\\"test\\")
|
||||||
|
|
||||||
export const render = _withId(function render(_ctx, _cache) {
|
export const render = /*#__PURE__*/ _withId(function render(_ctx, _cache) {
|
||||||
return (_openBlock(), _createBlock(\\"div\\"))
|
return (_openBlock(), _createBlock(\\"div\\"))
|
||||||
})"
|
})"
|
||||||
`;
|
`;
|
||||||
|
@ -20,8 +20,10 @@ describe('scopeId compiler support', () => {
|
|||||||
scopeId: 'test'
|
scopeId: 'test'
|
||||||
})
|
})
|
||||||
expect(ast.helpers).toContain(WITH_SCOPE_ID)
|
expect(ast.helpers).toContain(WITH_SCOPE_ID)
|
||||||
expect(code).toMatch(`const _withId = _withScopeId("test")`)
|
expect(code).toMatch(`const _withId = /*#__PURE__*/ _withScopeId("test")`)
|
||||||
expect(code).toMatch(`export const render = _withId(function render(`)
|
expect(code).toMatch(
|
||||||
|
`export const render = /*#__PURE__*/ _withId(function render(`
|
||||||
|
)
|
||||||
expect(code).toMatchSnapshot()
|
expect(code).toMatchSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -83,10 +85,10 @@ describe('scopeId compiler support', () => {
|
|||||||
expect(code).toMatch(
|
expect(code).toMatch(
|
||||||
[
|
[
|
||||||
`_pushScopeId("test")`,
|
`_pushScopeId("test")`,
|
||||||
`const _hoisted_1 = _createVNode("div", null, "hello", ${genFlagText(
|
`const _hoisted_1 = /*#__PURE__*/ _createVNode("div", null, "hello", ${genFlagText(
|
||||||
PatchFlags.HOISTED
|
PatchFlags.HOISTED
|
||||||
)})`,
|
)})`,
|
||||||
`const _hoisted_2 = _createVNode("div", null, "world", ${genFlagText(
|
`const _hoisted_2 = /*#__PURE__*/ _createVNode("div", null, "world", ${genFlagText(
|
||||||
PatchFlags.HOISTED
|
PatchFlags.HOISTED
|
||||||
)})`,
|
)})`,
|
||||||
`_popScopeId()`
|
`_popScopeId()`
|
||||||
|
@ -4,7 +4,7 @@ exports[`compiler: hoistStatic transform hoist element with static key 1`] = `
|
|||||||
"const _Vue = Vue
|
"const _Vue = Vue
|
||||||
const { createVNode: _createVNode } = _Vue
|
const { createVNode: _createVNode } = _Vue
|
||||||
|
|
||||||
const _hoisted_1 = _createVNode(\\"div\\", { key: \\"foo\\" }, null, -1 /* HOISTED */)
|
const _hoisted_1 = /*#__PURE__*/ _createVNode(\\"div\\", { key: \\"foo\\" }, null, -1 /* HOISTED */)
|
||||||
|
|
||||||
return function render(_ctx, _cache) {
|
return function render(_ctx, _cache) {
|
||||||
with (_ctx) {
|
with (_ctx) {
|
||||||
@ -21,7 +21,7 @@ exports[`compiler: hoistStatic transform hoist nested static tree 1`] = `
|
|||||||
"const _Vue = Vue
|
"const _Vue = Vue
|
||||||
const { createVNode: _createVNode } = _Vue
|
const { createVNode: _createVNode } = _Vue
|
||||||
|
|
||||||
const _hoisted_1 = _createVNode(\\"p\\", null, [
|
const _hoisted_1 = /*#__PURE__*/ _createVNode(\\"p\\", null, [
|
||||||
_createVNode(\\"span\\"),
|
_createVNode(\\"span\\"),
|
||||||
_createVNode(\\"span\\")
|
_createVNode(\\"span\\")
|
||||||
], -1 /* HOISTED */)
|
], -1 /* HOISTED */)
|
||||||
@ -41,7 +41,7 @@ exports[`compiler: hoistStatic transform hoist nested static tree with comments
|
|||||||
"const _Vue = Vue
|
"const _Vue = Vue
|
||||||
const { createVNode: _createVNode, createCommentVNode: _createCommentVNode } = _Vue
|
const { createVNode: _createVNode, createCommentVNode: _createCommentVNode } = _Vue
|
||||||
|
|
||||||
const _hoisted_1 = _createVNode(\\"div\\", null, [
|
const _hoisted_1 = /*#__PURE__*/ _createVNode(\\"div\\", null, [
|
||||||
_createCommentVNode(\\"comment\\")
|
_createCommentVNode(\\"comment\\")
|
||||||
], -1 /* HOISTED */)
|
], -1 /* HOISTED */)
|
||||||
|
|
||||||
@ -60,8 +60,8 @@ exports[`compiler: hoistStatic transform hoist siblings with common non-hoistabl
|
|||||||
"const _Vue = Vue
|
"const _Vue = Vue
|
||||||
const { createVNode: _createVNode } = _Vue
|
const { createVNode: _createVNode } = _Vue
|
||||||
|
|
||||||
const _hoisted_1 = _createVNode(\\"span\\", null, null, -1 /* HOISTED */)
|
const _hoisted_1 = /*#__PURE__*/ _createVNode(\\"span\\", null, null, -1 /* HOISTED */)
|
||||||
const _hoisted_2 = _createVNode(\\"div\\", null, null, -1 /* HOISTED */)
|
const _hoisted_2 = /*#__PURE__*/ _createVNode(\\"div\\", null, null, -1 /* HOISTED */)
|
||||||
|
|
||||||
return function render(_ctx, _cache) {
|
return function render(_ctx, _cache) {
|
||||||
with (_ctx) {
|
with (_ctx) {
|
||||||
@ -79,7 +79,7 @@ exports[`compiler: hoistStatic transform hoist simple element 1`] = `
|
|||||||
"const _Vue = Vue
|
"const _Vue = Vue
|
||||||
const { createVNode: _createVNode } = _Vue
|
const { createVNode: _createVNode } = _Vue
|
||||||
|
|
||||||
const _hoisted_1 = _createVNode(\\"span\\", { class: \\"inline\\" }, \\"hello\\", -1 /* HOISTED */)
|
const _hoisted_1 = /*#__PURE__*/ _createVNode(\\"span\\", { class: \\"inline\\" }, \\"hello\\", -1 /* HOISTED */)
|
||||||
|
|
||||||
return function render(_ctx, _cache) {
|
return function render(_ctx, _cache) {
|
||||||
with (_ctx) {
|
with (_ctx) {
|
||||||
@ -172,7 +172,7 @@ exports[`compiler: hoistStatic transform prefixIdentifiers hoist nested static t
|
|||||||
"const _Vue = Vue
|
"const _Vue = Vue
|
||||||
const { createVNode: _createVNode } = _Vue
|
const { createVNode: _createVNode } = _Vue
|
||||||
|
|
||||||
const _hoisted_1 = _createVNode(\\"span\\", null, \\"foo \\" + _toDisplayString(1) + \\" \\" + _toDisplayString(true), -1 /* HOISTED */)
|
const _hoisted_1 = /*#__PURE__*/ _createVNode(\\"span\\", null, \\"foo \\" + _toDisplayString(1) + \\" \\" + _toDisplayString(true), -1 /* HOISTED */)
|
||||||
|
|
||||||
return function render(_ctx, _cache) {
|
return function render(_ctx, _cache) {
|
||||||
with (_ctx) {
|
with (_ctx) {
|
||||||
@ -189,7 +189,7 @@ exports[`compiler: hoistStatic transform prefixIdentifiers hoist nested static t
|
|||||||
"const _Vue = Vue
|
"const _Vue = Vue
|
||||||
const { createVNode: _createVNode } = _Vue
|
const { createVNode: _createVNode } = _Vue
|
||||||
|
|
||||||
const _hoisted_1 = _createVNode(\\"span\\", { foo: 0 }, _toDisplayString(1), -1 /* HOISTED */)
|
const _hoisted_1 = /*#__PURE__*/ _createVNode(\\"span\\", { foo: 0 }, _toDisplayString(1), -1 /* HOISTED */)
|
||||||
|
|
||||||
return function render(_ctx, _cache) {
|
return function render(_ctx, _cache) {
|
||||||
with (_ctx) {
|
with (_ctx) {
|
||||||
@ -346,7 +346,7 @@ exports[`compiler: hoistStatic transform should hoist v-for children if static 1
|
|||||||
const { createVNode: _createVNode } = _Vue
|
const { createVNode: _createVNode } = _Vue
|
||||||
|
|
||||||
const _hoisted_1 = { id: \\"foo\\" }
|
const _hoisted_1 = { id: \\"foo\\" }
|
||||||
const _hoisted_2 = _createVNode(\\"span\\", null, null, -1 /* HOISTED */)
|
const _hoisted_2 = /*#__PURE__*/ _createVNode(\\"span\\", null, null, -1 /* HOISTED */)
|
||||||
|
|
||||||
return function render(_ctx, _cache) {
|
return function render(_ctx, _cache) {
|
||||||
with (_ctx) {
|
with (_ctx) {
|
||||||
@ -371,7 +371,7 @@ const _hoisted_1 = {
|
|||||||
key: 0,
|
key: 0,
|
||||||
id: \\"foo\\"
|
id: \\"foo\\"
|
||||||
}
|
}
|
||||||
const _hoisted_2 = _createVNode(\\"span\\", null, null, -1 /* HOISTED */)
|
const _hoisted_2 = /*#__PURE__*/ _createVNode(\\"span\\", null, null, -1 /* HOISTED */)
|
||||||
|
|
||||||
return function render(_ctx, _cache) {
|
return function render(_ctx, _cache) {
|
||||||
with (_ctx) {
|
with (_ctx) {
|
||||||
|
@ -201,7 +201,7 @@ export function generate(
|
|||||||
|
|
||||||
// enter render function
|
// enter render function
|
||||||
if (genScopeId && !ssr) {
|
if (genScopeId && !ssr) {
|
||||||
push(`const render = _withId(`)
|
push(`const render = /*#__PURE__*/ _withId(`)
|
||||||
}
|
}
|
||||||
if (!ssr) {
|
if (!ssr) {
|
||||||
push(`function render(_ctx, _cache) {`)
|
push(`function render(_ctx, _cache) {`)
|
||||||
@ -400,7 +400,7 @@ function genModulePreamble(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (genScopeId) {
|
if (genScopeId) {
|
||||||
push(`const _withId = ${helper(WITH_SCOPE_ID)}("${scopeId}")`)
|
push(`const _withId = /*#__PURE__*/ ${helper(WITH_SCOPE_ID)}("${scopeId}")`)
|
||||||
newline()
|
newline()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,6 +445,13 @@ function genHoists(hoists: JSChildNode[], context: CodegenContext) {
|
|||||||
|
|
||||||
hoists.forEach((exp, i) => {
|
hoists.forEach((exp, i) => {
|
||||||
push(`const _hoisted_${i + 1} = `)
|
push(`const _hoisted_${i + 1} = `)
|
||||||
|
// make hosit function calls tree-shakable
|
||||||
|
if (
|
||||||
|
exp.type === NodeTypes.VNODE_CALL ||
|
||||||
|
exp.type === NodeTypes.JS_CALL_EXPRESSION
|
||||||
|
) {
|
||||||
|
push(`/*#__PURE__*/ `)
|
||||||
|
}
|
||||||
genNode(exp, context)
|
genNode(exp, context)
|
||||||
newline()
|
newline()
|
||||||
})
|
})
|
||||||
|
@ -45,7 +45,7 @@ function walk(
|
|||||||
) {
|
) {
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
const child = children[i]
|
const child = children[i]
|
||||||
// only plain elements are eligible for hoisting.
|
// only plain elements & text calls are eligible for hoisting.
|
||||||
if (
|
if (
|
||||||
child.type === NodeTypes.ELEMENT &&
|
child.type === NodeTypes.ELEMENT &&
|
||||||
child.tagType === ElementTypes.ELEMENT
|
child.tagType === ElementTypes.ELEMENT
|
||||||
@ -79,7 +79,14 @@ function walk(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (
|
||||||
|
child.type === NodeTypes.TEXT_CALL &&
|
||||||
|
isStaticNode(child.content, resultCache)
|
||||||
|
) {
|
||||||
|
child.codegenNode = context.hoist(child.codegenNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// walk further
|
||||||
if (child.type === NodeTypes.ELEMENT) {
|
if (child.type === NodeTypes.ELEMENT) {
|
||||||
walk(child.children, context, resultCache)
|
walk(child.children, context, resultCache)
|
||||||
} else if (child.type === NodeTypes.FOR) {
|
} else if (child.type === NodeTypes.FOR) {
|
||||||
@ -91,11 +98,6 @@ function walk(
|
|||||||
// Do not hoist v-if single child because it has to be a block
|
// Do not hoist v-if single child because it has to be a block
|
||||||
walk(branchChildren, context, resultCache, branchChildren.length === 1)
|
walk(branchChildren, context, resultCache, branchChildren.length === 1)
|
||||||
}
|
}
|
||||||
} else if (
|
|
||||||
child.type === NodeTypes.TEXT_CALL &&
|
|
||||||
isStaticNode(child.content, resultCache)
|
|
||||||
) {
|
|
||||||
child.codegenNode = context.hoist(child.codegenNode)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user