Skip to content

Commit 1434590

Browse files
committed
feat: support option experimentalInlineMatchResource
1 parent dba0e43 commit 1434590

10 files changed

+155
-93
lines changed

Diff for: jest.config.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
console.log(`running tests with webpack ${process.env.WEBPACK4 ? '4' : '5'}...`)
1+
const isWebpack4 = process.env.WEBPACK4
2+
3+
console.log(
4+
`running tests with webpack ${isWebpack4 ? '4' : '5'}${
5+
!isWebpack4 && process.env.INLINE_MATCH_RESOURCE
6+
? ' with inline match resource enabled'
7+
: ''
8+
}...`
9+
)
210

311
module.exports = {
412
preset: 'ts-jest',

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"build": "tsc",
1515
"pretest": "tsc",
1616
"test": "jest",
17+
"test:match-resource": "INLINE_MATCH_RESOURCE=true jest",
1718
"pretest:webpack4": "tsc",
1819
"test:webpack4": "WEBPACK4=true jest",
1920
"dev-example": "node example/devServer.js --config example/webpack.config.js --inline --hot",

Diff for: src/index.ts

+21-18
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export interface VueLoaderOptions {
5151
exposeFilename?: boolean
5252
appendExtension?: boolean
5353
enableTsInTemplate?: boolean
54+
experimentalInlineMatchResource?: boolean
5455

5556
isServerBuild?: boolean
5657
}
@@ -59,7 +60,6 @@ let errorEmitted = false
5960

6061
const { parse } = compiler
6162
const exportHelperPath = JSON.stringify(require.resolve('./exportHelper'))
62-
// const vueLoader = __filename
6363

6464
export default function loader(
6565
this: LoaderContext<VueLoaderOptions>,
@@ -102,6 +102,9 @@ export default function loader(
102102
const resourceQuery = rawQuery ? `&${rawQuery}` : ''
103103
const options = (getOptions(loaderContext) || {}) as VueLoaderOptions
104104

105+
const enableInlineMatchResource =
106+
isWebpack5 && Boolean(options.experimentalInlineMatchResource)
107+
105108
const isServer = options.isServerBuild ?? target === 'node'
106109
const isProduction =
107110
mode === 'production' || process.env.NODE_ENV === 'production'
@@ -182,18 +185,14 @@ export default function loader(
182185

183186
let scriptRequest: string
184187

185-
if (isWebpack5) {
188+
if (enableInlineMatchResource) {
186189
scriptRequest = stringifyRequest(
187190
genMatchResource(this, src, query, lang || 'js')
188191
)
189192
} else {
190193
scriptRequest = stringifyRequest(src + query)
191194
}
192195

193-
// stringifyRequest(
194-
// isWebpack5 ? genMatchResource(src, query, lang || 'js') : src + query
195-
// )
196-
197196
scriptImport =
198197
`import script from ${scriptRequest}\n` +
199198
// support named exports
@@ -214,16 +213,20 @@ export default function loader(
214213
const tsQuery =
215214
options.enableTsInTemplate !== false && isTS ? `&ts=true` : ``
216215
const query = `?vue&type=template${idQuery}${scopedQuery}${tsQuery}${attrsQuery}${resourceQuery}${externalQuery}`
217-
templateRequest = stringifyRequest(
218-
isWebpack5
219-
? genMatchResource(
220-
this,
221-
src,
222-
query,
223-
options.enableTsInTemplate !== false && isTS ? 'ts' : 'js'
224-
)
225-
: src + query
226-
)
216+
217+
if (enableInlineMatchResource) {
218+
templateRequest = stringifyRequest(
219+
genMatchResource(
220+
this,
221+
src,
222+
query,
223+
options.enableTsInTemplate !== false && isTS ? 'ts' : 'js'
224+
)
225+
)
226+
} else {
227+
templateRequest = stringifyRequest(src + query)
228+
}
229+
227230
templateImport = `import { ${renderFnName} } from ${templateRequest}`
228231
propsToAttach.push([renderFnName, renderFnName])
229232
}
@@ -247,7 +250,7 @@ export default function loader(
247250
const query = `?vue&type=style&index=${i}${idQuery}${inlineQuery}${attrsQuery}${resourceQuery}${externalQuery}`
248251

249252
let styleRequest
250-
if (isWebpack5) {
253+
if (enableInlineMatchResource) {
251254
styleRequest = stringifyRequest(
252255
genMatchResource(this, src, query, lang)
253256
)
@@ -333,7 +336,7 @@ export default function loader(
333336

334337
let customRequest
335338

336-
if (isWebpack5) {
339+
if (enableInlineMatchResource) {
337340
customRequest = stringifyRequest(
338341
genMatchResource(
339342
this,

Diff for: src/pitcher.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ export const pitch = function () {
6262
const isWebpack5 = webpackVersion && webpackVersion[0] > '4'
6363
if (query.type === `style`) {
6464
if (isWebpack5 && context._compiler?.options.experiments.css) {
65-
if (query.inline) {
65+
if (query.inline || query.module) {
6666
context.emitError(
67-
new Error('`inline` is not supported with `experiments.css` enabled')
67+
new Error(
68+
'`inline` or `module` is currently not supported with `experiments.css` enabled'
69+
)
6870
)
6971
return ''
7072
}

Diff for: src/pluginWebpack5.ts

+55-47
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ class VueLoaderPlugin {
146146
)
147147
}
148148

149-
// get the normlized "use" for vue files
149+
// get the normalized "use" for vue files
150150
const vueUse = vueRules
151151
.filter((rule) => rule.type === 'use')
152152
.map((rule) => rule.value)
@@ -170,6 +170,8 @@ class VueLoaderPlugin {
170170
const vueLoaderUse = vueUse[vueLoaderUseIndex]
171171
const vueLoaderOptions = (vueLoaderUse.options =
172172
vueLoaderUse.options || {}) as VueLoaderOptions
173+
const enableInlineMatchResource =
174+
vueLoaderOptions.experimentalInlineMatchResource
173175

174176
// for each user rule (except the vue rule), create a cloned rule
175177
// that targets the corresponding language blocks in *.vue files.
@@ -202,13 +204,13 @@ class VueLoaderPlugin {
202204
// match it against the compiled template code inside *.vue files, so that
203205
// compiled vue render functions receive the same treatment as user code
204206
// (mostly babel)
205-
// const jsRulesForRenderFn = rules
206-
// .filter(
207-
// (r) =>
208-
// r !== rawVueRule &&
209-
// (match(r, 'test.js').length > 0 || match(r, 'test.ts').length > 0)
210-
// )
211-
// .map((rawRule) => cloneRule(rawRule, refs, jsRuleCheck, jsRuleResource))
207+
const jsRulesForRenderFn = rules
208+
.filter(
209+
(r) =>
210+
r !== rawVueRule &&
211+
(match(r, 'test.js').length > 0 || match(r, 'test.ts').length > 0)
212+
)
213+
.map((rawRule) => cloneRule(rawRule, refs, jsRuleCheck, jsRuleResource))
212214

213215
// global pitcher (responsible for injecting template compiler loader & CSS
214216
// post loader)
@@ -223,44 +225,50 @@ class VueLoaderPlugin {
223225
},
224226
}
225227

226-
const vueLoaderRules = rules.filter((rule) => {
227-
const use = rule.use
228-
229-
if (!use) {
230-
return false
231-
}
232-
233-
const matchOnce = (use: RuleSetUse) => {
234-
let loaderString = ''
235-
if (typeof use === 'string') {
236-
loaderString = use
237-
} else if (Array.isArray(use)) {
238-
loaderString = matchOnce(use[0])
239-
} else if (typeof use === 'object' && use.loader) {
240-
loaderString = use.loader
228+
// replace original rules
229+
if (enableInlineMatchResource) {
230+
// Match rules using `vue-loader`
231+
const vueLoaderRules = rules.filter((rule) => {
232+
const use = rule.use
233+
if (!use) {
234+
return false
241235
}
242236

243-
return loaderString
244-
}
245-
246-
const loader = matchOnce(use)
247-
248-
if (loader.startsWith('vue-loader')) {
249-
return true
250-
}
237+
const matchOnce = (use: RuleSetUse) => {
238+
let loaderString = ''
239+
if (typeof use === 'string') {
240+
loaderString = use
241+
} else if (Array.isArray(use)) {
242+
loaderString = matchOnce(use[0])
243+
} else if (typeof use === 'object' && use.loader) {
244+
loaderString = use.loader
245+
}
246+
return loaderString
247+
}
251248

252-
return loader.startsWith(require.resolve('./index'))
253-
})
249+
const loader = matchOnce(use)
250+
return (
251+
loader === require('../package.json').name ||
252+
loader.startsWith(require.resolve('./index'))
253+
)
254+
})
254255

255-
// replace original rules
256-
compiler.options.module!.rules = [
257-
pitcher,
258-
// ...jsRulesForRenderFn,
259-
...rules.filter((rule) => !vueLoaderRules.includes(rule)),
260-
templateCompilerRule,
261-
...clonedRules,
262-
...vueLoaderRules,
263-
]
256+
compiler.options.module!.rules = [
257+
pitcher,
258+
...rules.filter((rule) => !vueLoaderRules.includes(rule)),
259+
templateCompilerRule,
260+
...clonedRules,
261+
...vueLoaderRules,
262+
]
263+
} else {
264+
compiler.options.module!.rules = [
265+
pitcher,
266+
...jsRulesForRenderFn,
267+
templateCompilerRule,
268+
...clonedRules,
269+
...rules,
270+
]
271+
}
264272

265273
// 3.3 HMR support for imported types
266274
if (
@@ -333,12 +341,12 @@ const langBlockRuleResource = (
333341
resource: string
334342
): string => `${resource}.${query.lang}`
335343

336-
// const jsRuleCheck = (query: qs.ParsedUrlQuery): boolean => {
337-
// return query.type === 'template'
338-
// }
344+
const jsRuleCheck = (query: qs.ParsedUrlQuery): boolean => {
345+
return query.type === 'template'
346+
}
339347

340-
// const jsRuleResource = (query: qs.ParsedUrlQuery, resource: string): string =>
341-
// `${resource}.${query.ts ? `ts` : `js`}`
348+
const jsRuleResource = (query: qs.ParsedUrlQuery, resource: string): string =>
349+
`${resource}.${query.ts ? `ts` : `js`}`
342350

343351
let uid = 0
344352

Diff for: test/advanced.spec.ts

+15-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { SourceMapConsumer } from 'source-map'
22
import { fs as mfs } from 'memfs'
3-
import { bundle, mockBundleAndRun, normalizeNewline, genId } from './utils'
3+
import {
4+
bundle,
5+
mockBundleAndRun,
6+
normalizeNewline,
7+
genId,
8+
DEFAULT_VUE_USE,
9+
} from './utils'
410

511
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
612

@@ -10,7 +16,7 @@ test('support chaining with other loaders', async () => {
1016
modify: (config) => {
1117
config!.module!.rules[0] = {
1218
test: /\.vue$/,
13-
use: ['vue-loader', require.resolve('./mock-loaders/js')],
19+
use: [DEFAULT_VUE_USE, require.resolve('./mock-loaders/js')],
1420
}
1521
},
1622
})
@@ -24,7 +30,7 @@ test.skip('inherit queries on files', async () => {
2430
modify: (config) => {
2531
config!.module!.rules[0] = {
2632
test: /\.vue$/,
27-
use: ['vue-loader', require.resolve('./mock-loaders/query')],
33+
use: [DEFAULT_VUE_USE, require.resolve('./mock-loaders/query')],
2834
}
2935
},
3036
})
@@ -92,7 +98,7 @@ test('extract CSS', async () => {
9298
config.module.rules = [
9399
{
94100
test: /\.vue$/,
95-
use: 'vue-loader',
101+
use: [DEFAULT_VUE_USE],
96102
},
97103
{
98104
test: /\.css$/,
@@ -126,7 +132,7 @@ test('extract CSS with code spliting', async () => {
126132
config.module.rules = [
127133
{
128134
test: /\.vue$/,
129-
use: 'vue-loader',
135+
use: [DEFAULT_VUE_USE],
130136
},
131137
{
132138
test: /\.css$/,
@@ -153,7 +159,10 @@ test('support rules with oneOf', async () => {
153159
entry,
154160
modify: (config: any) => {
155161
config!.module!.rules = [
156-
{ test: /\.vue$/, loader: 'vue-loader' },
162+
{
163+
test: /\.vue$/,
164+
use: [DEFAULT_VUE_USE],
165+
},
157166
{
158167
test: /\.css$/,
159168
use: 'style-loader',

Diff for: test/edgeCases.spec.ts

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import * as path from 'path'
22
import webpack from 'webpack'
3-
import { mfs, bundle, mockBundleAndRun, normalizeNewline } from './utils'
3+
import {
4+
mfs,
5+
bundle,
6+
mockBundleAndRun,
7+
normalizeNewline,
8+
DEFAULT_VUE_USE,
9+
} from './utils'
410

511
// @ts-ignore
612
function assertComponent({
@@ -37,7 +43,7 @@ test('vue rule with include', async () => {
3743
config.module.rules[i] = {
3844
test: /\.vue$/,
3945
include: /fixtures/,
40-
loader: 'vue-loader',
46+
use: [DEFAULT_VUE_USE],
4147
}
4248
},
4349
})
@@ -52,7 +58,7 @@ test('test-less oneOf rules', async () => {
5258
config!.module!.rules = [
5359
{
5460
test: /\.vue$/,
55-
loader: 'vue-loader',
61+
use: [DEFAULT_VUE_USE],
5662
},
5763
{
5864
oneOf: [
@@ -79,12 +85,7 @@ test('normalize multiple use + options', async () => {
7985
)
8086
config!.module!.rules[i] = {
8187
test: /\.vue$/,
82-
use: [
83-
{
84-
loader: 'vue-loader',
85-
options: {},
86-
},
87-
],
88+
use: [DEFAULT_VUE_USE],
8889
}
8990
},
9091
})

0 commit comments

Comments
 (0)