diff --git a/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap index ae00fd8d..f599fcfa 100644 --- a/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap +++ b/packages/compiler-core/__tests__/__snapshots__/codegen.spec.ts.snap @@ -90,7 +90,7 @@ exports[`compiler: codegen comment 1`] = ` " return function render() { with (this) { - return _createVNode(_Comment, null, \\"foo\\") + return _createCommentVNode(\\"foo\\") } }" `; diff --git a/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap index 7e156f32..3f7f1c59 100644 --- a/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap +++ b/packages/compiler-core/__tests__/__snapshots__/compile.spec.ts.snap @@ -5,13 +5,13 @@ exports[`compiler: integration tests function mode 1`] = ` return function render() { with (this) { - const { toString: _toString, openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Comment: _Comment, Fragment: _Fragment, renderList: _renderList, Text: _Text } = _Vue + const { toString: _toString, openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment, renderList: _renderList, createTextVNode: _createTextVNode } = _Vue return (_openBlock(), _createBlock(\\"div\\", { id: \\"foo\\", class: bar.baz }, [ - _createVNode(_Text, null, _toString(world.burn()) + \\" \\", 1 /* TEXT */), + _createTextVNode(_toString(world.burn()) + \\" \\", 1 /* TEXT */), (_openBlock(), ok ? _createBlock(\\"div\\", { key: 0 }, \\"yes\\") : _createBlock(_Fragment, { key: 1 }, [\\"no\\"])), @@ -26,7 +26,7 @@ return function render() { `; exports[`compiler: integration tests function mode w/ prefixIdentifiers: true 1`] = ` -"const { toString, openBlock, createVNode, createBlock, Comment, Fragment, renderList, Text } = Vue +"const { toString, openBlock, createVNode, createBlock, createCommentVNode, Fragment, renderList, createTextVNode } = Vue return function render() { const _ctx = this @@ -34,7 +34,7 @@ return function render() { id: \\"foo\\", class: _ctx.bar.baz }, [ - createVNode(Text, null, toString(_ctx.world.burn()) + \\" \\", 1 /* TEXT */), + createTextVNode(toString(_ctx.world.burn()) + \\" \\", 1 /* TEXT */), (openBlock(), (_ctx.ok) ? createBlock(\\"div\\", { key: 0 }, \\"yes\\") : createBlock(Fragment, { key: 1 }, [\\"no\\"])), @@ -48,7 +48,7 @@ return function render() { `; exports[`compiler: integration tests module mode 1`] = ` -"import { toString, openBlock, createVNode, createBlock, Comment, Fragment, renderList, Text } from \\"vue\\" +"import { toString, openBlock, createVNode, createBlock, createCommentVNode, Fragment, renderList, createTextVNode } from \\"vue\\" export default function render() { const _ctx = this @@ -56,7 +56,7 @@ export default function render() { id: \\"foo\\", class: _ctx.bar.baz }, [ - createVNode(Text, null, toString(_ctx.world.burn()) + \\" \\", 1 /* TEXT */), + createTextVNode(toString(_ctx.world.burn()) + \\" \\", 1 /* TEXT */), (openBlock(), (_ctx.ok) ? createBlock(\\"div\\", { key: 0 }, \\"yes\\") : createBlock(Fragment, { key: 1 }, [\\"no\\"])), diff --git a/packages/compiler-core/__tests__/codegen.spec.ts b/packages/compiler-core/__tests__/codegen.spec.ts index d9de2654..c356dbac 100644 --- a/packages/compiler-core/__tests__/codegen.spec.ts +++ b/packages/compiler-core/__tests__/codegen.spec.ts @@ -18,11 +18,11 @@ import { } from '../src' import { CREATE_VNODE, - COMMENT, TO_STRING, RESOLVE_DIRECTIVE, helperNameMap, - RESOLVE_COMPONENT + RESOLVE_COMPONENT, + CREATE_COMMENT } from '../src/runtimeHelpers' import { createElementWithCodegen } from './testUtils' import { PatchFlags } from '@vue/shared' @@ -149,7 +149,6 @@ describe('compiler: codegen', () => { codegenNode: { type: NodeTypes.TEXT, content: 'hello', - isEmpty: false, loc: locStub } }) @@ -178,11 +177,7 @@ describe('compiler: codegen', () => { } }) ) - expect(code).toMatch( - `return _${helperNameMap[CREATE_VNODE]}(_${ - helperNameMap[COMMENT] - }, null, "foo")` - ) + expect(code).toMatch(`return _${helperNameMap[CREATE_COMMENT]}("foo")`) expect(code).toMatchSnapshot() }) diff --git a/packages/compiler-core/__tests__/parse.spec.ts b/packages/compiler-core/__tests__/parse.spec.ts index 84f4b94a..dd2372c6 100644 --- a/packages/compiler-core/__tests__/parse.spec.ts +++ b/packages/compiler-core/__tests__/parse.spec.ts @@ -1612,6 +1612,14 @@ foo expect(ast.children.every(c => c.type === NodeTypes.ELEMENT)).toBe(true) }) + it('should remove whitespaces adjacent to comments', () => { + const ast = parse(`
\n
`) + expect(ast.children.length).toBe(3) + expect(ast.children[0].type).toBe(NodeTypes.ELEMENT) + expect(ast.children[1].type).toBe(NodeTypes.COMMENT) + expect(ast.children[2].type).toBe(NodeTypes.ELEMENT) + }) + it('should remove whitespaces w/ newline between comments and elements', () => { const ast = parse(`
\n \n
`) expect(ast.children.length).toBe(3) diff --git a/packages/compiler-core/__tests__/transform.spec.ts b/packages/compiler-core/__tests__/transform.spec.ts index 2190ad11..f2660e64 100644 --- a/packages/compiler-core/__tests__/transform.spec.ts +++ b/packages/compiler-core/__tests__/transform.spec.ts @@ -9,13 +9,12 @@ import { import { ErrorCodes, createCompilerError } from '../src/errors' import { TO_STRING, - CREATE_VNODE, - COMMENT, OPEN_BLOCK, CREATE_BLOCK, FRAGMENT, RENDER_SLOT, - WITH_DIRECTIVES + WITH_DIRECTIVES, + CREATE_COMMENT } from '../src/runtimeHelpers' import { transformIf } from '../src/transforms/vIf' import { transformFor } from '../src/transforms/vFor' @@ -232,8 +231,7 @@ describe('compiler: transform', () => { test('should inject createVNode and Comment for comments', () => { const ast = parse(``) transform(ast, {}) - expect(ast.helpers).toContain(CREATE_VNODE) - expect(ast.helpers).toContain(COMMENT) + expect(ast.helpers).toContain(CREATE_COMMENT) }) describe('root codegenNode', () => { diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap index 47d6ed8c..aa7fd9b6 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/hoistStatic.spec.ts.snap @@ -40,15 +40,15 @@ return function render() { exports[`compiler: hoistStatic transform hoist nested static tree with comments 1`] = ` "const _Vue = Vue const _createVNode = Vue.createVNode -const _Comment = Vue.Comment +const _createCommentVNode = Vue.createCommentVNode const _hoisted_1 = _createVNode(\\"div\\", null, [ - _createVNode(_Comment, null, \\"comment\\") + _createCommentVNode(\\"comment\\") ]) return function render() { with (this) { - const { createVNode: _createVNode, Comment: _Comment, createBlock: _createBlock, openBlock: _openBlock } = _Vue + const { createCommentVNode: _createCommentVNode, createVNode: _createVNode, createBlock: _createBlock, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(\\"div\\", null, [ _hoisted_1 @@ -372,7 +372,7 @@ return function render() { exports[`compiler: hoistStatic transform should hoist v-if props/children if static 1`] = ` "const _Vue = Vue const _createVNode = Vue.createVNode -const _Comment = Vue.Comment +const _createCommentVNode = Vue.createCommentVNode const _hoisted_1 = { key: 0, @@ -382,14 +382,14 @@ const _hoisted_2 = _createVNode(\\"span\\") return function render() { with (this) { - const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Comment: _Comment } = _Vue + const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue return (_openBlock(), _createBlock(\\"div\\", null, [ (_openBlock(), ok ? _createBlock(\\"div\\", _hoisted_1, [ _hoisted_2 ]) - : _createBlock(_Comment)) + : _createCommentVNode()) ])) } }" diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap index 9e1f736a..e0327d8a 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/transformText.spec.ts.snap @@ -17,11 +17,11 @@ exports[`compiler: transform text consecutive text between elements 1`] = ` return function render() { with (this) { - const { createVNode: _createVNode, toString: _toString, Text: _Text, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue + const { createVNode: _createVNode, toString: _toString, createTextVNode: _createTextVNode, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(_Fragment, null, [ _createVNode(\\"div\\"), - _createVNode(_Text, null, _toString(foo) + \\" bar \\" + _toString(baz), 1 /* TEXT */), + _createTextVNode(_toString(foo) + \\" bar \\" + _toString(baz), 1 /* TEXT */), _createVNode(\\"div\\") ])) } @@ -33,13 +33,13 @@ exports[`compiler: transform text consecutive text mixed with elements 1`] = ` return function render() { with (this) { - const { createVNode: _createVNode, toString: _toString, Text: _Text, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue + const { createVNode: _createVNode, toString: _toString, createTextVNode: _createTextVNode, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(_Fragment, null, [ _createVNode(\\"div\\"), - _createVNode(_Text, null, _toString(foo) + \\" bar \\" + _toString(baz), 1 /* TEXT */), + _createTextVNode(_toString(foo) + \\" bar \\" + _toString(baz), 1 /* TEXT */), _createVNode(\\"div\\"), - _createVNode(_Text, null, \\"hello\\"), + _createTextVNode(\\"hello\\"), _createVNode(\\"div\\") ])) } @@ -63,11 +63,11 @@ exports[`compiler: transform text text between elements (static) 1`] = ` return function render() { with (this) { - const { createVNode: _createVNode, Text: _Text, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue + const { createVNode: _createVNode, createTextVNode: _createTextVNode, createBlock: _createBlock, Fragment: _Fragment, openBlock: _openBlock } = _Vue return (_openBlock(), _createBlock(_Fragment, null, [ _createVNode(\\"div\\"), - _createVNode(_Text, null, \\"hello\\"), + _createTextVNode(\\"hello\\"), _createVNode(\\"div\\") ])) } diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap index abf124ed..af3a901b 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vFor.spec.ts.snap @@ -155,13 +155,13 @@ exports[`compiler: v-for codegen v-if + v-for 1`] = ` return function render() { with (this) { - const { openBlock: _openBlock, renderList: _renderList, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode, Comment: _Comment } = _Vue + const { openBlock: _openBlock, renderList: _renderList, createBlock: _createBlock, Fragment: _Fragment, createVNode: _createVNode, createCommentVNode: _createCommentVNode } = _Vue return (_openBlock(), ok ? _createBlock(_Fragment, { key: 0 }, _renderList(list, (i) => { return (_openBlock(), _createBlock(\\"div\\")) }), 128 /* UNKEYED_FRAGMENT */) - : _createBlock(_Comment)) + : _createCommentVNode()) } }" `; diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/vIf.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/vIf.spec.ts.snap index fdb9a82d..2ae79ffd 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/vIf.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/vIf.spec.ts.snap @@ -5,11 +5,11 @@ exports[`compiler: v-if codegen basic v-if 1`] = ` return function render() { with (this) { - const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Comment: _Comment } = _Vue + const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue return (_openBlock(), ok ? _createBlock(\\"div\\", { key: 0 }) - : _createBlock(_Comment)) + : _createCommentVNode()) } }" `; @@ -19,7 +19,7 @@ exports[`compiler: v-if codegen template v-if 1`] = ` return function render() { with (this) { - const { openBlock: _openBlock, createVNode: _createVNode, Fragment: _Fragment, createBlock: _createBlock, Comment: _Comment } = _Vue + const { openBlock: _openBlock, createVNode: _createVNode, Fragment: _Fragment, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue return (_openBlock(), ok ? _createBlock(_Fragment, { key: 0 }, [ @@ -27,7 +27,7 @@ return function render() { \\"hello\\", _createVNode(\\"p\\") ]) - : _createBlock(_Comment)) + : _createCommentVNode()) } }" `; @@ -37,11 +37,11 @@ exports[`compiler: v-if codegen template v-if w/ single child 1`] = ` return function render() { with (this) { - const { openBlock: _openBlock, renderSlot: _renderSlot, createBlock: _createBlock, Comment: _Comment } = _Vue + const { openBlock: _openBlock, renderSlot: _renderSlot, createCommentVNode: _createCommentVNode } = _Vue return (_openBlock(), ok ? _renderSlot($slots, \\"default\\", { key: 0 }) - : _createBlock(_Comment)) + : _createCommentVNode()) } }" `; @@ -51,7 +51,7 @@ exports[`compiler: v-if codegen v-if + v-else 1`] = ` return function render() { with (this) { - const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Comment: _Comment } = _Vue + const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue return (_openBlock(), ok ? _createBlock(\\"div\\", { key: 0 }) @@ -65,7 +65,7 @@ exports[`compiler: v-if codegen v-if + v-else-if + v-else 1`] = ` return function render() { with (this) { - const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Comment: _Comment, Fragment: _Fragment } = _Vue + const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, createCommentVNode: _createCommentVNode, Fragment: _Fragment } = _Vue return (_openBlock(), ok ? _createBlock(\\"div\\", { key: 0 }) @@ -81,13 +81,13 @@ exports[`compiler: v-if codegen v-if + v-else-if 1`] = ` return function render() { with (this) { - const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, Comment: _Comment } = _Vue + const { openBlock: _openBlock, createVNode: _createVNode, createBlock: _createBlock, createCommentVNode: _createCommentVNode } = _Vue return (_openBlock(), ok ? _createBlock(\\"div\\", { key: 0 }) : orNot ? _createBlock(\\"p\\", { key: 1 }) - : _createBlock(_Comment)) + : _createCommentVNode()) } }" `; @@ -97,11 +97,11 @@ exports[`compiler: v-if codegen v-if on 1`] = ` return function render() { with (this) { - const { openBlock: _openBlock, renderSlot: _renderSlot, createBlock: _createBlock, Comment: _Comment } = _Vue + const { openBlock: _openBlock, renderSlot: _renderSlot, createCommentVNode: _createCommentVNode } = _Vue return (_openBlock(), ok ? _renderSlot($slots, \\"default\\", { key: 0 }) - : _createBlock(_Comment)) + : _createCommentVNode()) } }" `; diff --git a/packages/compiler-core/__tests__/transforms/transformText.spec.ts b/packages/compiler-core/__tests__/transforms/transformText.spec.ts index ec43e0dd..3c427c7f 100644 --- a/packages/compiler-core/__tests__/transforms/transformText.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformText.spec.ts @@ -8,7 +8,7 @@ import { import { transformText } from '../../src/transforms/transformText' import { transformExpression } from '../../src/transforms/transformExpression' import { transformElement } from '../../src/transforms/transformElement' -import { CREATE_VNODE, TEXT } from '../../src/runtimeHelpers' +import { CREATE_TEXT } from '../../src/runtimeHelpers' import { genFlagText } from '../testUtils' import { PatchFlags } from '@vue/shared' @@ -62,10 +62,8 @@ describe('compiler: transform text', () => { type: NodeTypes.TEXT_CALL, codegenNode: { type: NodeTypes.JS_CALL_EXPRESSION, - callee: CREATE_VNODE, + callee: CREATE_TEXT, arguments: [ - TEXT, - `null`, { type: NodeTypes.COMPOUND_EXPRESSION, children: [ @@ -93,10 +91,8 @@ describe('compiler: transform text', () => { type: NodeTypes.TEXT_CALL, codegenNode: { type: NodeTypes.JS_CALL_EXPRESSION, - callee: CREATE_VNODE, + callee: CREATE_TEXT, arguments: [ - TEXT, - `null`, { type: NodeTypes.TEXT, content: `hello` @@ -119,10 +115,8 @@ describe('compiler: transform text', () => { type: NodeTypes.TEXT_CALL, codegenNode: { type: NodeTypes.JS_CALL_EXPRESSION, - callee: CREATE_VNODE, + callee: CREATE_TEXT, arguments: [ - TEXT, - `null`, { type: NodeTypes.COMPOUND_EXPRESSION, children: [ @@ -142,10 +136,8 @@ describe('compiler: transform text', () => { type: NodeTypes.TEXT_CALL, codegenNode: { type: NodeTypes.JS_CALL_EXPRESSION, - callee: CREATE_VNODE, + callee: CREATE_TEXT, arguments: [ - TEXT, - `null`, { type: NodeTypes.TEXT, content: `hello` diff --git a/packages/compiler-core/__tests__/transforms/vIf.spec.ts b/packages/compiler-core/__tests__/transforms/vIf.spec.ts index 4ca81333..7e347023 100644 --- a/packages/compiler-core/__tests__/transforms/vIf.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vIf.spec.ts @@ -19,11 +19,11 @@ import { CompilerOptions, generate } from '../../src' import { OPEN_BLOCK, CREATE_BLOCK, - COMMENT, FRAGMENT, MERGE_PROPS, WITH_DIRECTIVES, - RENDER_SLOT + RENDER_SLOT, + CREATE_COMMENT } from '../../src/runtimeHelpers' import { createObjectMatcher } from '../testUtils' @@ -265,7 +265,11 @@ describe('compiler: v-if', () => { }) describe('codegen', () => { - function assertSharedCodegen(node: SequenceExpression, depth: number = 0) { + function assertSharedCodegen( + node: SequenceExpression, + depth: number = 0, + hasElse: boolean = false + ) { expect(node).toMatchObject({ type: NodeTypes.JS_SEQUENCE_EXPRESSION, expressions: [ @@ -287,7 +291,7 @@ describe('compiler: v-if', () => { depth < 1 ? { type: NodeTypes.JS_CALL_EXPRESSION, - callee: CREATE_BLOCK + callee: hasElse ? CREATE_BLOCK : CREATE_COMMENT } : { type: NodeTypes.JS_CONDITIONAL_EXPRESSION, @@ -300,7 +304,7 @@ describe('compiler: v-if', () => { }, alternate: { type: NodeTypes.JS_CALL_EXPRESSION, - callee: CREATE_BLOCK + callee: hasElse ? CREATE_BLOCK : CREATE_COMMENT } } } @@ -322,7 +326,10 @@ describe('compiler: v-if', () => { ]) const branch2 = (codegenNode.expressions[1] as ConditionalExpression) .alternate as CallExpression - expect(branch2.arguments).toMatchObject([COMMENT]) + expect(branch2).toMatchObject({ + type: NodeTypes.JS_CALL_EXPRESSION, + callee: CREATE_COMMENT + }) expect(generate(root).code).toMatchSnapshot() }) @@ -345,7 +352,10 @@ describe('compiler: v-if', () => { ]) const branch2 = (codegenNode.expressions[1] as ConditionalExpression) .alternate as CallExpression - expect(branch2.arguments).toMatchObject([COMMENT]) + expect(branch2).toMatchObject({ + type: NodeTypes.JS_CALL_EXPRESSION, + callee: CREATE_COMMENT + }) expect(generate(root).code).toMatchSnapshot() }) @@ -386,7 +396,7 @@ describe('compiler: v-if', () => { root, node: { codegenNode } } = parseWithIfTransform(`

`) - assertSharedCodegen(codegenNode) + assertSharedCodegen(codegenNode, 0, true) const branch1 = (codegenNode.expressions[1] as ConditionalExpression) .consequent as CallExpression expect(branch1.arguments).toMatchObject([ @@ -430,7 +440,7 @@ describe('compiler: v-if', () => { } = parseWithIfTransform( `

` ) - assertSharedCodegen(codegenNode, 1) + assertSharedCodegen(codegenNode, 1, true) const branch1 = (codegenNode.expressions[1] as ConditionalExpression) .consequent as CallExpression expect(branch1.arguments).toMatchObject([ diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts index 04384ceb..99531868 100644 --- a/packages/compiler-core/src/codegen.ts +++ b/packages/compiler-core/src/codegen.ts @@ -29,13 +29,13 @@ import { } from './utils' import { isString, isArray, isSymbol } from '@vue/shared' import { + helperNameMap, TO_STRING, CREATE_VNODE, - COMMENT, - helperNameMap, RESOLVE_COMPONENT, RESOLVE_DIRECTIVE, - SET_BLOCK_TRACKING + SET_BLOCK_TRACKING, + CREATE_COMMENT } from './runtimeHelpers' type CodegenNode = TemplateChildNode | JSChildNode @@ -212,9 +212,17 @@ export function generate( // has check cost, but hoists are lifted out of the function - we need // to provide the helper here. if (ast.hoists.length) { - push(`const _${helperNameMap[CREATE_VNODE]} = Vue.createVNode\n`) - if (ast.helpers.includes(COMMENT)) { - push(`const _${helperNameMap[COMMENT]} = Vue.Comment\n`) + push( + `const _${helperNameMap[CREATE_VNODE]} = Vue.${ + helperNameMap[CREATE_VNODE] + }\n` + ) + if (ast.helpers.includes(CREATE_COMMENT)) { + push( + `const _${helperNameMap[CREATE_COMMENT]} = Vue.${ + helperNameMap[CREATE_COMMENT] + }\n` + ) } } } @@ -502,12 +510,7 @@ function genExpressionAsPropertyKey( function genComment(node: CommentNode, context: CodegenContext) { if (__DEV__) { const { push, helper } = context - push( - `${helper(CREATE_VNODE)}(${helper(COMMENT)}, null, ${JSON.stringify( - node.content - )})`, - node - ) + push(`${helper(CREATE_COMMENT)}(${JSON.stringify(node.content)})`, node) } } diff --git a/packages/compiler-core/src/parse.ts b/packages/compiler-core/src/parse.ts index 8b58b669..4b2cec42 100644 --- a/packages/compiler-core/src/parse.ts +++ b/packages/compiler-core/src/parse.ts @@ -218,15 +218,16 @@ function parseChildren( const next = nodes[i + 1] // If: // - the whitespace is the first or last node, or: - // - the whitespace contains newline AND is between two element or comments + // - the whitespace is adjacent to a comment, or: + // - the whitespace is between two elements AND contains newline // Then the whitespace is ignored. if ( !prev || !next || - ((prev.type === NodeTypes.ELEMENT || - prev.type === NodeTypes.COMMENT) && - (next.type === NodeTypes.ELEMENT || - next.type === NodeTypes.COMMENT) && + prev.type === NodeTypes.COMMENT || + next.type === NodeTypes.COMMENT || + (prev.type === NodeTypes.ELEMENT && + next.type === NodeTypes.ELEMENT && /[\r\n]/.test(node.content)) ) { removedWhitespace = true diff --git a/packages/compiler-core/src/runtimeHelpers.ts b/packages/compiler-core/src/runtimeHelpers.ts index a2ed747b..f6963168 100644 --- a/packages/compiler-core/src/runtimeHelpers.ts +++ b/packages/compiler-core/src/runtimeHelpers.ts @@ -1,11 +1,11 @@ export const FRAGMENT = Symbol(__DEV__ ? `Fragment` : ``) export const PORTAL = Symbol(__DEV__ ? `Portal` : ``) -export const COMMENT = Symbol(__DEV__ ? `Comment` : ``) -export const TEXT = Symbol(__DEV__ ? `Text` : ``) export const SUSPENSE = Symbol(__DEV__ ? `Suspense` : ``) export const OPEN_BLOCK = Symbol(__DEV__ ? `openBlock` : ``) export const CREATE_BLOCK = Symbol(__DEV__ ? `createBlock` : ``) export const CREATE_VNODE = Symbol(__DEV__ ? `createVNode` : ``) +export const CREATE_COMMENT = Symbol(__DEV__ ? `createCommentVNode` : ``) +export const CREATE_TEXT = Symbol(__DEV__ ? `createTextVNode` : ``) export const RESOLVE_COMPONENT = Symbol(__DEV__ ? `resolveComponent` : ``) export const RESOLVE_DYNAMIC_COMPONENT = Symbol( __DEV__ ? `resolveDynamicComponent` : `` @@ -27,12 +27,12 @@ export const SET_BLOCK_TRACKING = Symbol(__DEV__ ? `setBlockTracking` : ``) export const helperNameMap: any = { [FRAGMENT]: `Fragment`, [PORTAL]: `Portal`, - [COMMENT]: `Comment`, - [TEXT]: `Text`, [SUSPENSE]: `Suspense`, [OPEN_BLOCK]: `openBlock`, [CREATE_BLOCK]: `createBlock`, [CREATE_VNODE]: `createVNode`, + [CREATE_COMMENT]: `createCommentVNode`, + [CREATE_TEXT]: `createTextVNode`, [RESOLVE_COMPONENT]: `resolveComponent`, [RESOLVE_DYNAMIC_COMPONENT]: `resolveDynamicComponent`, [RESOLVE_DIRECTIVE]: `resolveDirective`, diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts index f00656e8..88125d32 100644 --- a/packages/compiler-core/src/transform.ts +++ b/packages/compiler-core/src/transform.ts @@ -21,12 +21,11 @@ import { isString, isArray } from '@vue/shared' import { CompilerError, defaultOnError } from './errors' import { TO_STRING, - COMMENT, - CREATE_VNODE, FRAGMENT, helperNameMap, WITH_DIRECTIVES, - CREATE_BLOCK + CREATE_BLOCK, + CREATE_COMMENT } from './runtimeHelpers' import { isVSlot, createBlockExpression } from './utils' import { hoistStatic, isSingleElementRoot } from './transforms/hoistStatic' @@ -346,8 +345,7 @@ export function traverseNode( case NodeTypes.COMMENT: // inject import for the Comment symbol, which is needed for creating // comment nodes with `createVNode` - context.helper(CREATE_VNODE) - context.helper(COMMENT) + context.helper(CREATE_COMMENT) break case NodeTypes.INTERPOLATION: // no need to traverse, but we need to inject toString helper diff --git a/packages/compiler-core/src/transforms/transformText.ts b/packages/compiler-core/src/transforms/transformText.ts index 1251a30d..25bf22d4 100644 --- a/packages/compiler-core/src/transforms/transformText.ts +++ b/packages/compiler-core/src/transforms/transformText.ts @@ -5,9 +5,10 @@ import { TextNode, InterpolationNode, CompoundExpressionNode, - createCallExpression + createCallExpression, + CallExpression } from '../ast' -import { TEXT, CREATE_VNODE } from '../runtimeHelpers' +import { CREATE_TEXT } from '../runtimeHelpers' import { PatchFlags, PatchFlagNames } from '@vue/shared' const isText = ( @@ -54,11 +55,17 @@ export const transformText: NodeTransform = (node, context) => { if (hasText && children.length > 1) { // when an element has mixed text/element children, convert text nodes - // into createVNode(Text) calls. + // into createTextVNode(text) calls. for (let i = 0; i < children.length; i++) { const child = children[i] if (isText(child) || child.type === NodeTypes.COMPOUND_EXPRESSION) { - const callArgs = [context.helper(TEXT), `null`, child] + const callArgs: CallExpression['arguments'] = [] + // createTextVNode defaults to single whitespace, so if it is a + // single space the code could be an empty call to save bytes. + if (child.type !== NodeTypes.TEXT || child.content !== ' ') { + callArgs.push(child) + } + // mark dynamic text with flag so it gets patched inside a block if (child.type !== NodeTypes.TEXT) { callArgs.push( `${PatchFlags.TEXT} /* ${PatchFlagNames[PatchFlags.TEXT]} */` @@ -69,7 +76,7 @@ export const transformText: NodeTransform = (node, context) => { content: child, loc: child.loc, codegenNode: createCallExpression( - context.helper(CREATE_VNODE), + context.helper(CREATE_TEXT), callArgs ) } diff --git a/packages/compiler-core/src/transforms/vIf.ts b/packages/compiler-core/src/transforms/vIf.ts index 5f6c4140..e3da963c 100644 --- a/packages/compiler-core/src/transforms/vIf.ts +++ b/packages/compiler-core/src/transforms/vIf.ts @@ -30,10 +30,10 @@ import { processExpression } from './transformExpression' import { OPEN_BLOCK, CREATE_BLOCK, - COMMENT, FRAGMENT, WITH_DIRECTIVES, - CREATE_VNODE + CREATE_VNODE, + CREATE_COMMENT } from '../runtimeHelpers' import { injectProp } from '../utils' @@ -152,9 +152,7 @@ function createCodegenNodeForBranch( return createConditionalExpression( branch.condition, createChildrenCodegenNode(branch, index, context), - createCallExpression(context.helper(CREATE_BLOCK), [ - context.helper(COMMENT) - ]) + createCallExpression(context.helper(CREATE_COMMENT)) ) as IfConditionalExpression } else { return createChildrenCodegenNode(branch, index, context) as BlockCodegenNode diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index ceb4c6b2..5e09505d 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -49,7 +49,7 @@ export { toString } from './helpers/toString' export { toHandlers } from './helpers/toHandlers' export { renderSlot } from './helpers/renderSlot' export { createSlots } from './helpers/createSlots' -export { setBlockTracking } from './vnode' +export { setBlockTracking, createTextVNode } from './vnode' export { capitalize, camelize } from '@vue/shared' // Internal, for integration with runtime compiler diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index 2f167b64..41c2cd74 100644 --- a/packages/runtime-core/src/vnode.ts +++ b/packages/runtime-core/src/vnode.ts @@ -19,10 +19,10 @@ import { AppContext } from './apiApp' import { SuspenseBoundary } from './suspense' export const Fragment = __DEV__ ? Symbol('Fragment') : Symbol() -export const Text = __DEV__ ? Symbol('Text') : Symbol() -export const Comment = __DEV__ ? Symbol('Comment') : Symbol() export const Portal = __DEV__ ? Symbol('Portal') : Symbol() export const Suspense = __DEV__ ? Symbol('Suspense') : Symbol() +export const Text = __DEV__ ? Symbol('Text') : Symbol() +export const Comment = __DEV__ ? Symbol('Comment') : Symbol() export type VNodeTypes = | string @@ -254,6 +254,14 @@ export function cloneVNode(vnode: VNode): VNode { } } +export function createTextVNode(text: string = ' ', flag: number = 0): VNode { + return createVNode(Text, null, text, flag) +} + +export function createCommentVNode(text: string = ''): VNode { + return createVNode(Comment, null, text) +} + export function normalizeVNode(child: VNodeChild): VNode { if (child == null) { // empty placeholder