refactor(compiler-vapor): inline literal value into template

This commit is contained in:
三咲智子 Kevin Deng 2024-05-29 16:17:10 +08:00
parent 107569b922
commit 00c6e6dc73
No known key found for this signature in database
6 changed files with 46 additions and 29 deletions

View File

@ -1,7 +1,7 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`compiler: children transform > children & sibling references 1`] = `
"import { next as _next, setText as _setText, createTextNode as _createTextNode, insert as _insert, template as _template } from 'vue/vapor';
"import { next as _next, createTextNode as _createTextNode, insert as _insert, renderEffect as _renderEffect, setText as _setText, template as _template } from 'vue/vapor';
const t0 = _template("<div><p></p> <!><p></p></div>")
export function render(_ctx) {
@ -9,10 +9,10 @@ export function render(_ctx) {
const n0 = n4.firstChild
const n3 = _next(n0, 2)
const n2 = n3.nextSibling
_setText(n0, 'first')
const n1 = _createTextNode(['second', " ", 'third', " "])
_setText(n2, 'forth')
const n1 = _createTextNode(() => [_ctx.second, " ", _ctx.third, " "])
_insert(n1, n4, n3)
_renderEffect(() => _setText(n0, _ctx.first))
_renderEffect(() => _setText(n2, _ctx.forth))
return n4
}"
`;

View File

@ -23,12 +23,11 @@ export function render(_ctx) {
`;
exports[`v-text > should raise error if has no expression 1`] = `
"import { setText as _setText, template as _template } from 'vue/vapor';
"import { template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_setText(n0, "")
return n0
}"
`;

View File

@ -21,10 +21,10 @@ describe('compiler: children transform', () => {
test('children & sibling references', () => {
const { code, vaporHelpers } = compileWithElementTransform(
`<div>
<p>{{'first'}}</p>
{{'second'}}
{{'third'}}
<p>{{'forth'}}</p>
<p>{{ first }}</p>
{{ second }}
{{ third }}
<p>{{ forth }}</p>
</div>`,
)
expect(code).toMatchSnapshot()

View File

@ -11,7 +11,7 @@ import {
} from '@vue/compiler-dom'
import type { NodeTransform, TransformContext } from '../transform'
import { DynamicFlag, IRNodeTypes } from '../ir'
import { isConstantExpression } from '../utils'
import { getLiteralExpressionValue, isConstantExpression } from '../utils'
type TextLike = TextNode | InterpolationNode
const seen = new WeakMap<
@ -65,11 +65,16 @@ function processTextLikeContainer(
context: TransformContext<ElementNode>,
) {
const values = children.map(child => createTextLikeExpression(child, context))
context.registerEffect(values, {
type: IRNodeTypes.SET_TEXT,
element: context.reference(),
values,
})
const literals = values.map(getLiteralExpressionValue)
if (literals.every(l => l != null)) {
context.childrenTemplate = literals.map(l => String(l))
} else {
context.registerEffect(values, {
type: IRNodeTypes.SET_TEXT,
element: context.reference(),
values,
})
}
}
function createTextLikeExpression(node: TextLike, context: TransformContext) {

View File

@ -2,6 +2,7 @@ import { DOMErrorCodes, createDOMCompilerError } from '@vue/compiler-dom'
import { IRNodeTypes } from '../ir'
import { EMPTY_EXPRESSION } from './utils'
import type { DirectiveTransform } from '../transform'
import { getLiteralExpressionValue } from '../utils'
export const transformVText: DirectiveTransform = (dir, node, context) => {
let { exp, loc } = dir
@ -18,9 +19,14 @@ export const transformVText: DirectiveTransform = (dir, node, context) => {
context.childrenTemplate.length = 0
}
context.registerEffect([exp], {
type: IRNodeTypes.SET_TEXT,
element: context.reference(),
values: [exp],
})
const literal = getLiteralExpressionValue(exp)
if (literal != null) {
context.childrenTemplate = [String(literal)]
} else {
context.registerEffect([exp], {
type: IRNodeTypes.SET_TEXT,
element: context.reference(),
values: [exp],
})
}
}

View File

@ -1,4 +1,4 @@
import type { NumericLiteral, StringLiteral } from '@babel/types'
import type { BigIntLiteral, NumericLiteral, StringLiteral } from '@babel/types'
import { isGloballyAllowed } from '@vue/shared'
import {
type AttributeNode,
@ -55,13 +55,20 @@ export function resolveExpression(exp: SimpleExpressionNode) {
export function getLiteralExpressionValue(
exp: SimpleExpressionNode,
): number | string | null {
if (
!__BROWSER__ &&
exp.ast &&
['StringLiteral', 'NumericLiteral'].includes(exp.ast.type)
) {
return (exp.ast as StringLiteral | NumericLiteral).value
): number | string | boolean | null {
if (!__BROWSER__ && exp.ast) {
if (
['StringLiteral', 'NumericLiteral', 'BigIntLiteral'].includes(
exp.ast.type,
)
) {
return (exp.ast as StringLiteral | NumericLiteral | BigIntLiteral).value
} else if (
exp.ast.type === 'TemplateLiteral' &&
exp.ast.expressions.length === 0
) {
return exp.ast.quasis[0].value.cooked!
}
}
return exp.isStatic ? exp.content : null
}