fix(compiler-sfc): properly reuse hoisted asset imports

fix #4581
This commit is contained in:
Evan You
2021-09-16 13:33:02 -04:00
parent fc968d607b
commit 06c5bf53ab
3 changed files with 41 additions and 24 deletions

View File

@@ -5,6 +5,7 @@ import {
ExpressionNode,
NodeTransform,
NodeTypes,
SimpleExpressionNode,
SourceLocation,
TransformContext
} from '@vue/compiler-core'
@@ -153,30 +154,42 @@ function getImportsExpressionExp(
context: TransformContext
): ExpressionNode {
if (path) {
const existing = context.imports.find(i => i.path === path)
if (existing) {
return existing.exp as ExpressionNode
}
const name = `_imports_${context.imports.length}`
const exp = createSimpleExpression(
name,
false,
loc,
ConstantTypes.CAN_HOIST
)
context.imports.push({ exp, path })
if (hash && path) {
return context.hoist(
createSimpleExpression(
`${name} + '${hash}'`,
false,
loc,
ConstantTypes.CAN_HOIST
)
)
let name: string
let exp: SimpleExpressionNode
const existingIndex = context.imports.findIndex(i => i.path === path)
if (existingIndex > -1) {
name = `_imports_${existingIndex}`
exp = context.imports[existingIndex].exp as SimpleExpressionNode
} else {
name = `_imports_${context.imports.length}`
exp = createSimpleExpression(name, false, loc, ConstantTypes.CAN_HOIST)
context.imports.push({ exp, path })
}
if (!hash) {
return exp
}
const hashExp = `${name} + '${hash}'`
const existingHoistIndex = context.hoists.findIndex(h => {
return (
h &&
h.type === NodeTypes.SIMPLE_EXPRESSION &&
!h.isStatic &&
h.content === hashExp
)
})
if (existingHoistIndex > -1) {
return createSimpleExpression(
`_hoisted_${existingHoistIndex + 1}`,
false,
loc,
ConstantTypes.CAN_HOIST
)
}
return context.hoist(
createSimpleExpression(hashExp, false, loc, ConstantTypes.CAN_HOIST)
)
} else {
return createSimpleExpression(`''`, false, loc, ConstantTypes.CAN_HOIST)
}