1
+ import path from "node:path" ;
1
2
import type { PluginOption , ResolvedConfig } from "vite" ;
2
3
import createCache from "./cache" ;
3
4
import { genComponentBlockCode , genExportsCode } from "./gen" ;
4
5
import { parseVueRequest , pascalCase } from "./utils" ;
5
6
6
7
export default function vueNestedSFC ( ) : PluginOption {
7
- const prefix = "virtual:vue-nested-sfc" ;
8
-
9
8
let config : ResolvedConfig ;
10
9
let cache : ReturnType < typeof createCache > ;
11
10
12
11
return {
13
- name : "vue-nested-sfc" ,
12
+ name : "vite: vue-nested-sfc" ,
14
13
15
14
configResolved ( resolvedConfig ) {
16
15
config = resolvedConfig ;
@@ -20,19 +19,34 @@ export default function vueNestedSFC(): PluginOption {
20
19
cache = createCache ( config ) ;
21
20
} ,
22
21
23
- resolveId ( id ) {
24
- if ( id . startsWith ( prefix ) ) {
22
+ resolveId ( id , importerFile ) {
23
+ if ( cache . isNestedComponent ( id ) ) {
25
24
return id ;
26
25
}
26
+ if ( importerFile && cache . isNestedComponent ( importerFile ) ) {
27
+ let [ , importerDir ] = importerFile . match ( / ^ ( .* ) (?: \/ [ ^ / ] + ) { 2 } \. v u e $ / ) ! ;
28
+ if ( ! importerDir . startsWith ( config . root ) ) {
29
+ importerDir = config . root + importerDir ;
30
+ }
31
+ return path . resolve ( importerDir , id ) ;
32
+ }
27
33
} ,
28
34
29
35
load ( id ) {
30
- if ( ! id . startsWith ( prefix ) ) {
36
+ if ( ! cache . isNestedComponent ( id ) ) {
31
37
return ;
32
38
}
33
39
34
- const [ , filename , component ] =
35
- id . slice ( prefix . length ) . match ( / ^ ( .* ) \/ ( [ ^ / ] + ) \. v u e $ / ) || [ ] ;
40
+ const match = id . match ( / ^ ( .* ) \/ ( [ ^ / ] + ) \. v u e $ / ) ;
41
+ if ( ! match ) {
42
+ return ;
43
+ }
44
+ let filename = match [ 1 ] ;
45
+ const component = match [ 2 ] ;
46
+
47
+ if ( ! filename . startsWith ( config . root ) ) {
48
+ filename = config . root + filename ;
49
+ }
36
50
37
51
const descriptor = cache . getDescriptor ( filename ) ;
38
52
@@ -53,21 +67,27 @@ export default function vueNestedSFC(): PluginOption {
53
67
transform ( code , id ) {
54
68
const request = parseVueRequest ( id ) ;
55
69
56
- if ( request . filename . startsWith ( prefix ) ) {
70
+ if ( cache . isNestedComponent ( id ) ) {
57
71
return ;
58
72
}
59
73
60
74
if ( ! request . query . vue && request . filename . endsWith ( ".vue" ) ) {
61
- return genExportsCode (
62
- prefix + request . filename ,
63
- cache . getNestedComponents ( id ) ,
64
- code
65
- ) ;
75
+ const components = cache . getNestedComponents ( id ) ;
76
+ for ( const componentName of components ) {
77
+ cache . registerNestedComponent ( request . filename , componentName ) ;
78
+ }
79
+ return {
80
+ code : genExportsCode ( request . filename , components , code ) ,
81
+ // eslint-disable-next-line unicorn/no-null
82
+ map : null ,
83
+ } ;
66
84
} else if ( request . query . type === "component" && request . query . name ) {
67
- return genComponentBlockCode (
68
- prefix + request . filename ,
69
- pascalCase ( request . query . name )
70
- ) ;
85
+ const componentName = pascalCase ( request . query . name ) ;
86
+ cache . registerNestedComponent ( request . filename , componentName ) ;
87
+ return {
88
+ code : genComponentBlockCode ( request . filename , componentName ) ,
89
+ map : { mappings : "" } ,
90
+ } ;
71
91
}
72
92
} ,
73
93
@@ -117,9 +137,11 @@ export default function vueNestedSFC(): PluginOption {
117
137
if ( ! nextBlock || block . content === nextBlock . content ) {
118
138
continue ;
119
139
}
120
- const componentModule = server . moduleGraph . getModuleById (
121
- `${ prefix } ${ file } /${ name } .vue`
122
- ) ;
140
+ const componentModule =
141
+ server . moduleGraph . getModuleById ( `${ file } /${ name } .vue` ) ||
142
+ server . moduleGraph . getModuleById (
143
+ `${ file . replace ( config . root , "" ) } /${ name } .vue`
144
+ ) ;
123
145
if ( ! componentModule ) {
124
146
continue ;
125
147
}
@@ -129,10 +151,15 @@ export default function vueNestedSFC(): PluginOption {
129
151
m . url . includes ( "type=component" ) &&
130
152
m . url . includes ( `name=${ nextBlock . attrs . name } ` )
131
153
) ;
132
- if ( ! blockModule ) {
133
- continue ;
154
+ if ( blockModule ) {
155
+ affectedModules . add ( blockModule ) ;
156
+ }
157
+ const subModules = [ ...componentModule . importedModules ] . filter ( ( m ) =>
158
+ m . url . startsWith ( componentModule . url )
159
+ ) ;
160
+ for ( const subModule of subModules ) {
161
+ affectedModules . add ( subModule ) ;
134
162
}
135
- affectedModules . add ( blockModule ) ;
136
163
}
137
164
138
165
return [ ...affectedModules ] ;
0 commit comments