Skip to content

Commit 06c5bf5

Browse files
committed
fix(compiler-sfc): properly reuse hoisted asset imports
fix #4581
1 parent fc968d6 commit 06c5bf5

File tree

3 files changed

+41
-24
lines changed

3 files changed

+41
-24
lines changed

Diff for: packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap

+5-2
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,17 @@ export function render(_ctx, _cache) {
3333
`;
3434

3535
exports[`compiler sfc: transform asset url support uri fragment 1`] = `
36-
"import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
36+
"import { createElementVNode as _createElementVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
3737
import _imports_0 from '@svg/file.svg'
3838
3939
4040
const _hoisted_1 = _imports_0 + '#fragment'
4141
4242
export function render(_ctx, _cache) {
43-
return (_openBlock(), _createElementBlock(\\"use\\", { href: _hoisted_1 }))
43+
return (_openBlock(), _createElementBlock(_Fragment, null, [
44+
_createElementVNode(\\"use\\", { href: _hoisted_1 }),
45+
_createElementVNode(\\"use\\", { href: _hoisted_1 })
46+
], 64 /* STABLE_FRAGMENT */))
4447
}"
4548
`;
4649

Diff for: packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ describe('compiler sfc: transform asset url', () => {
4141
*/
4242
test('support uri fragment', () => {
4343
const result = compileWithAssetUrls(
44-
'<use href="~@svg/file.svg#fragment"></use>'
44+
'<use href="~@svg/file.svg#fragment"></use>' +
45+
'<use href="~@svg/file.svg#fragment"></use>'
4546
)
4647

4748
expect(result.code).toMatchSnapshot()

Diff for: packages/compiler-sfc/src/templateTransformAssetUrl.ts

+34-21
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
ExpressionNode,
66
NodeTransform,
77
NodeTypes,
8+
SimpleExpressionNode,
89
SourceLocation,
910
TransformContext
1011
} from '@vue/compiler-core'
@@ -153,30 +154,42 @@ function getImportsExpressionExp(
153154
context: TransformContext
154155
): ExpressionNode {
155156
if (path) {
156-
const existing = context.imports.find(i => i.path === path)
157-
if (existing) {
158-
return existing.exp as ExpressionNode
159-
}
160-
const name = `_imports_${context.imports.length}`
161-
const exp = createSimpleExpression(
162-
name,
163-
false,
164-
loc,
165-
ConstantTypes.CAN_HOIST
166-
)
167-
context.imports.push({ exp, path })
168-
if (hash && path) {
169-
return context.hoist(
170-
createSimpleExpression(
171-
`${name} + '${hash}'`,
172-
false,
173-
loc,
174-
ConstantTypes.CAN_HOIST
175-
)
176-
)
157+
let name: string
158+
let exp: SimpleExpressionNode
159+
const existingIndex = context.imports.findIndex(i => i.path === path)
160+
if (existingIndex > -1) {
161+
name = `_imports_${existingIndex}`
162+
exp = context.imports[existingIndex].exp as SimpleExpressionNode
177163
} else {
164+
name = `_imports_${context.imports.length}`
165+
exp = createSimpleExpression(name, false, loc, ConstantTypes.CAN_HOIST)
166+
context.imports.push({ exp, path })
167+
}
168+
169+
if (!hash) {
178170
return exp
179171
}
172+
173+
const hashExp = `${name} + '${hash}'`
174+
const existingHoistIndex = context.hoists.findIndex(h => {
175+
return (
176+
h &&
177+
h.type === NodeTypes.SIMPLE_EXPRESSION &&
178+
!h.isStatic &&
179+
h.content === hashExp
180+
)
181+
})
182+
if (existingHoistIndex > -1) {
183+
return createSimpleExpression(
184+
`_hoisted_${existingHoistIndex + 1}`,
185+
false,
186+
loc,
187+
ConstantTypes.CAN_HOIST
188+
)
189+
}
190+
return context.hoist(
191+
createSimpleExpression(hashExp, false, loc, ConstantTypes.CAN_HOIST)
192+
)
180193
} else {
181194
return createSimpleExpression(`''`, false, loc, ConstantTypes.CAN_HOIST)
182195
}

0 commit comments

Comments
 (0)