wip: template binding optimization

This commit is contained in:
Evan You
2020-07-10 22:12:25 -04:00
parent b51b79f5c4
commit b6cdd5621e
12 changed files with 81 additions and 30 deletions

View File

@@ -1,8 +1,8 @@
// - Parse expressions in templates into compound expressions so that each
// identifier gets more accurate source-map locations.
//
// - Prefix identifiers with `_ctx.` so that they are accessed from the render
// context
// - Prefix identifiers with `_ctx.` or `$xxx` (for known binding types) so that
// they are accessed from the right source
//
// - This transform is only applied in non-browser builds because it relies on
// an additional JavaScript parser. In the browser, there is no source-map
@@ -25,7 +25,8 @@ import {
import {
isGloballyWhitelisted,
makeMap,
babelParserDefautPlugins
babelParserDefautPlugins,
hasOwn
} from '@vue/shared'
import { createCompilerError, ErrorCodes } from '../errors'
import { Node, Function, Identifier, ObjectProperty } from '@babel/types'
@@ -99,6 +100,14 @@ export function processExpression(
return node
}
const { bindingMetadata } = context
const prefix = (raw: string) => {
const source = hasOwn(bindingMetadata, raw)
? `$` + bindingMetadata[raw]
: `_ctx`
return `${source}.${raw}`
}
// fast path if expression is a simple identifier.
const rawExp = node.content
// bail on parens to prevent any possible function invocations.
@@ -110,7 +119,7 @@ export function processExpression(
!isGloballyWhitelisted(rawExp) &&
!isLiteralWhitelisted(rawExp)
) {
node.content = `_ctx.${rawExp}`
node.content = prefix(rawExp)
} else if (!context.identifiers[rawExp] && !bailConstant) {
// mark node constant for hoisting unless it's referring a scope variable
node.isConstant = true
@@ -148,7 +157,7 @@ export function processExpression(
const isDuplicate = (node: Node & PrefixMeta): boolean =>
ids.some(id => id.start === node.start)
// walk the AST and look for identifiers that need to be prefixed with `_ctx.`.
// walk the AST and look for identifiers that need to be prefixed.
walkJS(ast, {
enter(node: Node & PrefixMeta, parent) {
if (node.type === 'Identifier') {
@@ -160,7 +169,7 @@ export function processExpression(
// rewrite the value
node.prefix = `${node.name}: `
}
node.name = `_ctx.${node.name}`
node.name = prefix(node.name)
ids.push(node)
} else if (!isStaticPropertyKey(node, parent)) {
// The identifier is considered constant unless it's pointing to a