@@ -20,7 +20,12 @@ import { formatError } from './formatError'
20
20
import VueLoaderPlugin from './plugin'
21
21
import { canInlineTemplate } from './resolveScript'
22
22
import { setDescriptor } from './descriptorCache'
23
- import { getOptions , stringifyRequest as _stringifyRequest } from './util'
23
+ import {
24
+ getOptions ,
25
+ stringifyRequest as _stringifyRequest ,
26
+ genMatchResource ,
27
+ testWebpack5 ,
28
+ } from './util'
24
29
25
30
export { VueLoaderPlugin }
26
31
@@ -51,6 +56,7 @@ export interface VueLoaderOptions {
51
56
exposeFilename ?: boolean
52
57
appendExtension ?: boolean
53
58
enableTsInTemplate ?: boolean
59
+ experimentalInlineMatchResource ?: boolean
54
60
55
61
isServerBuild ?: boolean
56
62
}
@@ -90,18 +96,23 @@ export default function loader(
90
96
rootContext,
91
97
resourcePath,
92
98
resourceQuery : _resourceQuery = '' ,
99
+ _compiler,
93
100
} = loaderContext
94
101
102
+ const isWebpack5 = testWebpack5 ( _compiler )
95
103
const rawQuery = _resourceQuery . slice ( 1 )
96
104
const incomingQuery = qs . parse ( rawQuery )
97
105
const resourceQuery = rawQuery ? `&${ rawQuery } ` : ''
98
106
const options = ( getOptions ( loaderContext ) || { } ) as VueLoaderOptions
107
+ const enableInlineMatchResource =
108
+ isWebpack5 && Boolean ( options . experimentalInlineMatchResource )
99
109
100
110
const isServer = options . isServerBuild ?? target === 'node'
101
111
const isProduction =
102
112
mode === 'production' || process . env . NODE_ENV === 'production'
103
113
104
114
const filename = resourcePath . replace ( / \? .* $ / , '' )
115
+
105
116
const { descriptor, errors } = parse ( source , {
106
117
filename,
107
118
sourceMap,
@@ -167,10 +178,23 @@ export default function loader(
167
178
if ( script || scriptSetup ) {
168
179
const lang = script ?. lang || scriptSetup ?. lang
169
180
isTS = ! ! ( lang && / t s x ? / . test ( lang ) )
181
+ const externalQuery = Boolean ( script && ! scriptSetup && script . src )
182
+ ? `&external`
183
+ : ``
170
184
const src = ( script && ! scriptSetup && script . src ) || resourcePath
171
185
const attrsQuery = attrsToQuery ( ( scriptSetup || script ) ! . attrs , 'js' )
172
- const query = `?vue&type=script${ attrsQuery } ${ resourceQuery } `
173
- const scriptRequest = stringifyRequest ( src + query )
186
+ const query = `?vue&type=script${ attrsQuery } ${ resourceQuery } ${ externalQuery } `
187
+
188
+ let scriptRequest : string
189
+
190
+ if ( enableInlineMatchResource ) {
191
+ scriptRequest = stringifyRequest (
192
+ genMatchResource ( this , src , query , lang || 'js' )
193
+ )
194
+ } else {
195
+ scriptRequest = stringifyRequest ( src + query )
196
+ }
197
+
174
198
scriptImport =
175
199
`import script from ${ scriptRequest } \n` +
176
200
// support named exports
@@ -184,13 +208,27 @@ export default function loader(
184
208
const useInlineTemplate = canInlineTemplate ( descriptor , isProduction )
185
209
if ( descriptor . template && ! useInlineTemplate ) {
186
210
const src = descriptor . template . src || resourcePath
211
+ const externalQuery = Boolean ( descriptor . template . src ) ? `&external` : ``
187
212
const idQuery = `&id=${ id } `
188
213
const scopedQuery = hasScoped ? `&scoped=true` : ``
189
214
const attrsQuery = attrsToQuery ( descriptor . template . attrs )
190
215
const tsQuery =
191
216
options . enableTsInTemplate !== false && isTS ? `&ts=true` : ``
192
- const query = `?vue&type=template${ idQuery } ${ scopedQuery } ${ tsQuery } ${ attrsQuery } ${ resourceQuery } `
193
- templateRequest = stringifyRequest ( src + query )
217
+ const query = `?vue&type=template${ idQuery } ${ scopedQuery } ${ tsQuery } ${ attrsQuery } ${ resourceQuery } ${ externalQuery } `
218
+
219
+ if ( enableInlineMatchResource ) {
220
+ templateRequest = stringifyRequest (
221
+ genMatchResource (
222
+ this ,
223
+ src ,
224
+ query ,
225
+ options . enableTsInTemplate !== false && isTS ? 'ts' : 'js'
226
+ )
227
+ )
228
+ } else {
229
+ templateRequest = stringifyRequest ( src + query )
230
+ }
231
+
194
232
templateImport = `import { ${ renderFnName } } from ${ templateRequest } `
195
233
propsToAttach . push ( [ renderFnName , renderFnName ] )
196
234
}
@@ -205,12 +243,23 @@ export default function loader(
205
243
. forEach ( ( style , i ) => {
206
244
const src = style . src || resourcePath
207
245
const attrsQuery = attrsToQuery ( style . attrs , 'css' )
246
+ const lang = String ( style . attrs . lang || 'css' )
208
247
// make sure to only pass id when necessary so that we don't inject
209
248
// duplicate tags when multiple components import the same css file
210
249
const idQuery = ! style . src || style . scoped ? `&id=${ id } ` : ``
211
250
const inlineQuery = asCustomElement ? `&inline` : ``
212
- const query = `?vue&type=style&index=${ i } ${ idQuery } ${ inlineQuery } ${ attrsQuery } ${ resourceQuery } `
213
- const styleRequest = stringifyRequest ( src + query )
251
+ const externalQuery = Boolean ( style . src ) ? `&external` : ``
252
+ const query = `?vue&type=style&index=${ i } ${ idQuery } ${ inlineQuery } ${ attrsQuery } ${ resourceQuery } ${ externalQuery } `
253
+
254
+ let styleRequest
255
+ if ( enableInlineMatchResource ) {
256
+ styleRequest = stringifyRequest (
257
+ genMatchResource ( this , src , query , lang )
258
+ )
259
+ } else {
260
+ styleRequest = stringifyRequest ( src + query )
261
+ }
262
+
214
263
if ( style . module ) {
215
264
if ( asCustomElement ) {
216
265
loaderContext . emitError (
@@ -283,9 +332,27 @@ export default function loader(
283
332
const issuerQuery = block . attrs . src
284
333
? `&issuerPath=${ qs . escape ( resourcePath ) } `
285
334
: ''
286
- const query = `?vue&type=custom&index=${ i } ${ blockTypeQuery } ${ issuerQuery } ${ attrsQuery } ${ resourceQuery } `
335
+
336
+ const externalQuery = Boolean ( block . attrs . src ) ? `&external` : ``
337
+ const query = `?vue&type=custom&index=${ i } ${ blockTypeQuery } ${ issuerQuery } ${ attrsQuery } ${ resourceQuery } ${ externalQuery } `
338
+
339
+ let customRequest
340
+
341
+ if ( enableInlineMatchResource ) {
342
+ customRequest = stringifyRequest (
343
+ genMatchResource (
344
+ this ,
345
+ src as string ,
346
+ query ,
347
+ block . attrs . lang as string
348
+ )
349
+ )
350
+ } else {
351
+ customRequest = stringifyRequest ( src + query )
352
+ }
353
+
287
354
return (
288
- `import block${ i } from ${ stringifyRequest ( src + query ) } \n` +
355
+ `import block${ i } from ${ customRequest } \n` +
289
356
`if (typeof block${ i } === 'function') block${ i } (script)`
290
357
)
291
358
} )
0 commit comments