11import { genImport } from 'knitwork'
22import MagicString from 'magic-string'
3- import { basename , resolve } from 'node:path'
3+ import { parse , resolve } from 'node:path'
44import { parseSync , type CallExpression , type ImportDeclaration , type ImportDefaultSpecifier , type ImportSpecifier } from 'oxc-parser'
55import { createUnplugin } from 'unplugin'
66import { distDir } from '../dirs'
77import { findDefineComponentCalls } from './utils'
8+ import { useNuxt } from '@nuxt/kit'
9+ import type { Component } from '@nuxt/schema'
810
911const INCLUDE_FILES = / \. ( v u e | t s x ? | j s x ? ) $ /
1012// Exclude node_moduels as users can have control over it
1113const EXCLUDE_NODE_MODULES = / n o d e _ m o d u l e s /
1214const skipPath = normalizePath ( resolve ( distDir , 'runtime/lazy-load' ) )
1315
1416export const LazyLoadHintPlugin = createUnplugin ( ( ) => {
17+ const nuxt = useNuxt ( )
18+
19+ let nuxtComponents : Component [ ] = nuxt . apps . default ! . components
20+ nuxt . hook ( 'components:extend' , ( extendedComponents ) => {
21+ nuxtComponents = extendedComponents
22+ } )
23+
1524 return {
1625 name : '@nuxt/hints:lazy-load-plugin' ,
1726 enforce : 'post' ,
@@ -77,8 +86,9 @@ export const LazyLoadHintPlugin = createUnplugin(() => {
7786 const wrapperStatements = directComponentImports
7887 . map ( ( imp ) => {
7988 const originalName = `__original_${ imp . name } `
89+ const resolvedName = resolveComponentName ( imp , nuxtComponents )
8090 // Rename the import to __original_X and create a wrapped version as X
81- return `const ${ imp . name } = __wrapImportedComponent(${ originalName } , '${ imp . name } ', '${ imp . source } ', '${ normalizePath ( id ) } ')`
91+ return `const ${ imp . name } = __wrapImportedComponent(${ originalName } , '${ resolvedName } ', '${ imp . source } ', '${ normalizePath ( id ) } ')`
8292 } )
8393 . join ( '\n' )
8494
@@ -117,20 +127,16 @@ export const LazyLoadHintPlugin = createUnplugin(() => {
117127 // Inject useLazyComponentTracking in main component setup if applicable
118128 if ( code . includes ( '_sfc_main' ) ) {
119129 const wrappedComponents = directComponentImports . map ( ( imp ) => {
120- if ( imp . name . startsWith ( '__nuxt' ) ) {
121- // Auto imported components are using __nuxt_component_
122- // See nuxt loadeer plugin
123- return `{ componentName: '${ basename ( imp . source ) } ', importSource: '${ imp . source } ', importedBy: '${ normalizePath ( id ) } ', rendered: false }`
124- }
125- return `{ componentName: '${ imp . name } ', importSource: '${ imp . source } ', importedBy: '${ normalizePath ( id ) } ', rendered: false }`
130+ const componentName = resolveComponentName ( imp , nuxtComponents )
131+ return `{ componentName: '${ componentName } ', importSource: '${ imp . source } ', importedBy: '${ normalizePath ( id ) } ', rendered: false }`
126132 } ) . join ( ', ' )
127133 m . replace ( 'export default _sfc_main' , `const _sfc_main_wrapped = __wrapMainComponent(_sfc_main, [${ wrappedComponents } ]);\nexport default _sfc_main_wrapped` )
128134 }
129135 const components = findDefineComponentCalls ( program )
130136
131137 if ( components && components . length > 0 ) {
132138 for ( const comp of components ) {
133- injectUseLazyComponentTrackingInComponentSetup ( comp , m , directComponentImports , id )
139+ injectUseLazyComponentTrackingInComponentSetup ( comp , m , directComponentImports , id , nuxtComponents )
134140 }
135141 }
136142
@@ -151,13 +157,22 @@ function normalizePath(path: string): string {
151157 return path . replace ( / \\ / g, '/' )
152158}
153159
160+ function resolveComponentName (
161+ imp : { name : string , source : string } ,
162+ nuxtComponents : Component [ ] ,
163+ ) : string {
164+ const component = nuxtComponents . find ( c => c . filePath === imp . source )
165+ if ( component ) return component . pascalName
166+ return imp . name . startsWith ( '__nuxt' ) ? parse ( imp . source ) . name : imp . name
167+ }
168+
154169function injectUseLazyComponentTrackingInComponentSetup ( node : CallExpression , magicString : MagicString , directComponentImports : {
155170 name : string
156171 source : string
157172 start : number
158173 end : number
159174 specifier : ImportDefaultSpecifier | ImportSpecifier
160- } [ ] , id : string ) {
175+ } [ ] , id : string , nuxtComponents : Component [ ] ) {
161176 if ( node . arguments . length === 1 ) {
162177 const arg = node . arguments [ 0 ]
163178 if ( arg ?. type === 'ObjectExpression' ) {
@@ -173,7 +188,7 @@ function injectUseLazyComponentTrackingInComponentSetup(node: CallExpression, ma
173188 // Inject useLazyComponentTracking call at the start of the setup function body
174189 const insertPos = ( setupFunc . body ?. start ?? 0 ) + 1 // after {
175190 const componentsArray = directComponentImports . map ( ( imp ) => {
176- const componentName = imp . name . startsWith ( '__nuxt' ) ? basename ( imp . source ) : imp . name
191+ const componentName = resolveComponentName ( imp , nuxtComponents )
177192 return `{ componentName: '${ componentName } ', importSource: '${ imp . source } ', importedBy: '${ normalizePath ( id ) } ', rendered: false }`
178193 } ) . join ( ', ' )
179194 const injectionCode = `\nconst lazyHydrationState = useLazyComponentTracking([${ componentsArray } ]);\n`
0 commit comments