diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/importUsageCheck.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/importUsageCheck.spec.ts.snap
index 18946eb4b6d..8c32f25413a 100644
--- a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/importUsageCheck.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/importUsageCheck.spec.ts.snap
@@ -79,6 +79,21 @@ return { get FooBar() { return FooBar }, get foo() { return foo }, get bar() { r
})"
`;
+exports[`import namespace 1`] = `
+"import { defineComponent as _defineComponent } from 'vue'
+import * as Foo from './foo'
+
+export default /*#__PURE__*/_defineComponent({
+ setup(__props, { expose: __expose }) {
+ __expose();
+
+
+return { get Foo() { return Foo } }
+}
+
+})"
+`;
+
exports[`js template string interpolations 1`] = `
"import { defineComponent as _defineComponent } from 'vue'
import { VAR, VAR2, VAR3 } from './x'
diff --git a/packages/compiler-sfc/__tests__/compileScript/importUsageCheck.spec.ts b/packages/compiler-sfc/__tests__/compileScript/importUsageCheck.spec.ts
index 06631b2ceb4..d9fd1dfe529 100644
--- a/packages/compiler-sfc/__tests__/compileScript/importUsageCheck.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileScript/importUsageCheck.spec.ts
@@ -219,3 +219,17 @@ test('property access (whitespace)', () => {
expect(content).toMatch('return { get Foo() { return Foo } }')
assertCode(content)
})
+
+// #9974
+test('namespace / dot component usage', () => {
+ const { content } = compile(`
+
+
+
+
+ `)
+ expect(content).toMatch('return { get Foo() { return Foo } }')
+ assertCode(content)
+})
diff --git a/packages/compiler-sfc/src/script/importUsageCheck.ts b/packages/compiler-sfc/src/script/importUsageCheck.ts
index 5ea11f9157f..211efc49089 100644
--- a/packages/compiler-sfc/src/script/importUsageCheck.ts
+++ b/packages/compiler-sfc/src/script/importUsageCheck.ts
@@ -16,12 +16,12 @@ import { camelize, capitalize, isBuiltInDirective } from '@vue/shared'
* when not using inline mode.
*/
export function isImportUsed(local: string, sfc: SFCDescriptor): boolean {
- return resolveTemplateUsageCheckString(sfc).has(local)
+ return resolveTemplateUsedIdentifiers(sfc).has(local)
}
const templateUsageCheckCache = createCache>()
-function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
+function resolveTemplateUsedIdentifiers(sfc: SFCDescriptor): Set {
const { content, ast } = sfc.template!
const cached = templateUsageCheckCache.get(content)
if (cached) {
@@ -35,12 +35,14 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
function walk(node: TemplateChildNode) {
switch (node.type) {
case NodeTypes.ELEMENT:
+ let tag = node.tag
+ if (tag.includes('.')) tag = tag.split('.')[0].trim()
if (
- !parserOptions.isNativeTag!(node.tag) &&
- !parserOptions.isBuiltInComponent!(node.tag)
+ !parserOptions.isNativeTag!(tag) &&
+ !parserOptions.isBuiltInComponent!(tag)
) {
- ids.add(camelize(node.tag))
- ids.add(capitalize(camelize(node.tag)))
+ ids.add(camelize(tag))
+ ids.add(capitalize(camelize(tag)))
}
for (let i = 0; i < node.props.length; i++) {
const prop = node.props[i]