fix(compiler-sfc): fix treeshaking of namespace import when used in template

fix #5209
This commit is contained in:
Evan You 2022-05-12 18:56:54 +08:00
parent 8c51c6514f
commit 8a123ac34f
3 changed files with 14 additions and 3 deletions

View File

@ -777,6 +777,7 @@ exports[`SFC compile <script setup> inlineTemplate mode avoid unref() when neces
import { ref } from 'vue' import { ref } from 'vue'
import Foo, { bar } from './Foo.vue' import Foo, { bar } from './Foo.vue'
import other from './util' import other from './util'
import * as tree from './tree'
export default { export default {
setup(__props) { setup(__props) {
@ -795,7 +796,8 @@ return (_ctx, _cache) => {
]), ]),
_: 1 /* STABLE */ _: 1 /* STABLE */
}), }),
_createElementVNode(\\"div\\", { onClick: fn }, _toDisplayString(count.value) + \\" \\" + _toDisplayString(constant) + \\" \\" + _toDisplayString(_unref(maybe)) + \\" \\" + _toDisplayString(_unref(lett)) + \\" \\" + _toDisplayString(_unref(other)), 1 /* TEXT */) _createElementVNode(\\"div\\", { onClick: fn }, _toDisplayString(count.value) + \\" \\" + _toDisplayString(constant) + \\" \\" + _toDisplayString(_unref(maybe)) + \\" \\" + _toDisplayString(_unref(lett)) + \\" \\" + _toDisplayString(_unref(other)), 1 /* TEXT */),
_createTextVNode(\\" \\" + _toDisplayString(tree.foo()), 1 /* TEXT */)
], 64 /* STABLE_FRAGMENT */)) ], 64 /* STABLE_FRAGMENT */))
} }
} }

View File

@ -519,6 +519,7 @@ defineExpose({ foo: 123 })
import { ref } from 'vue' import { ref } from 'vue'
import Foo, { bar } from './Foo.vue' import Foo, { bar } from './Foo.vue'
import other from './util' import other from './util'
import * as tree from './tree'
const count = ref(0) const count = ref(0)
const constant = {} const constant = {}
const maybe = foo() const maybe = foo()
@ -528,6 +529,7 @@ defineExpose({ foo: 123 })
<template> <template>
<Foo>{{ bar }}</Foo> <Foo>{{ bar }}</Foo>
<div @click="fn">{{ count }} {{ constant }} {{ maybe }} {{ lett }} {{ other }}</div> <div @click="fn">{{ count }} {{ constant }} {{ maybe }} {{ lett }} {{ other }}</div>
{{ tree.foo() }}
</template> </template>
`, `,
{ inlineTemplate: true } { inlineTemplate: true }
@ -546,6 +548,8 @@ defineExpose({ foo: 123 })
expect(content).toMatch(`unref(maybe)`) expect(content).toMatch(`unref(maybe)`)
// should unref() on let bindings // should unref() on let bindings
expect(content).toMatch(`unref(lett)`) expect(content).toMatch(`unref(lett)`)
// no need to unref namespace import (this also preserves tree-shaking)
expect(content).toMatch(`tree.foo()`)
// no need to unref function declarations // no need to unref function declarations
expect(content).toMatch(`{ onClick: fn }`) expect(content).toMatch(`{ onClick: fn }`)
// no need to mark constant fns in patch flag // no need to mark constant fns in patch flag

View File

@ -1011,10 +1011,13 @@ export function compileScript(
for (let i = 0; i < node.specifiers.length; i++) { for (let i = 0; i < node.specifiers.length; i++) {
const specifier = node.specifiers[i] const specifier = node.specifiers[i]
const local = specifier.local.name const local = specifier.local.name
const imported = let imported =
specifier.type === 'ImportSpecifier' && specifier.type === 'ImportSpecifier' &&
specifier.imported.type === 'Identifier' && specifier.imported.type === 'Identifier' &&
specifier.imported.name specifier.imported.name
if (specifier.type === 'ImportNamespaceSpecifier') {
imported = '*'
}
const source = node.source.value const source = node.source.value
const existing = userImports[local] const existing = userImports[local]
if ( if (
@ -1257,7 +1260,9 @@ export function compileScript(
)) { )) {
if (isType) continue if (isType) continue
bindingMetadata[key] = bindingMetadata[key] =
(imported === 'default' && source.endsWith('.vue')) || source === 'vue' imported === '*' ||
(imported === 'default' && source.endsWith('.vue')) ||
source === 'vue'
? BindingTypes.SETUP_CONST ? BindingTypes.SETUP_CONST
: BindingTypes.SETUP_MAYBE_REF : BindingTypes.SETUP_MAYBE_REF
} }