Skip to content

Commit 0a5c79b

Browse files
arcanishaoqunjiang
authored andcommitted
Enforces require.resolve for loaders (#4532)
* Enforces require.resolve for loaders * Updates the lockfile * Fixes more things * Adds an extra check * test(loaders): fix the tests * style(cli): fix the linting * style(cli): fix the linting (on windows) * Update package.json * Updates the lockfile * chore: sync dependency versions * chore: sync dependency versions * chore: don't introduce unnecessary changes in yarn.lock * extraneous space
1 parent 2565c5d commit 0a5c79b

File tree

11 files changed

+74
-27
lines changed

11 files changed

+74
-27
lines changed

packages/@vue/babel-preset-app/package.json

+3
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,8 @@
3737
"babel-plugin-module-resolver": "^3.2.0",
3838
"core-js": "^3.3.2",
3939
"core-js-compat": "^3.3.2"
40+
},
41+
"peerDependencies": {
42+
"@babel/core": "*"
4043
}
4144
}

packages/@vue/cli-plugin-babel/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ module.exports = (api, options) => {
4545
})
4646
.end()
4747
.use('cache-loader')
48-
.loader('cache-loader')
48+
.loader(require.resolve('cache-loader'))
4949
.options(api.genCacheConfig('babel-loader', {
5050
'@babel/core': require('@babel/core/package.json').version,
5151
'@vue/babel-preset-app': require('@vue/babel-preset-app/package.json').version,
@@ -61,7 +61,7 @@ module.exports = (api, options) => {
6161
if (useThreads) {
6262
const threadLoaderConfig = jsRule
6363
.use('thread-loader')
64-
.loader('thread-loader')
64+
.loader(require.resolve('thread-loader'))
6565

6666
if (typeof options.parallel === 'number') {
6767
threadLoaderConfig.options({ workers: options.parallel })
@@ -70,6 +70,6 @@ module.exports = (api, options) => {
7070

7171
jsRule
7272
.use('babel-loader')
73-
.loader('babel-loader')
73+
.loader(require.resolve('babel-loader'))
7474
})
7575
}

packages/@vue/cli-plugin-babel/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
"@vue/babel-preset-app": "^4.0.5",
2525
"@vue/cli-shared-utils": "^4.0.5",
2626
"babel-loader": "^8.0.6",
27+
"cache-loader": "^4.1.0",
28+
"thread-loader": "^2.1.3",
2729
"webpack": "^4.0.0"
2830
},
2931
"peerDependencies": {

packages/@vue/cli-plugin-typescript/__tests__/tsPluginBabel.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ test('using correct loader', () => {
1616
const config = service.resolveWebpackConfig()
1717
// eslint-disable-next-line no-shadow
1818
const rule = config.module.rules.find(rule => rule.test.test('foo.ts'))
19-
expect(rule.use[0].loader).toMatch('cache-loader')
20-
expect(rule.use[1].loader).toMatch('babel-loader')
21-
expect(rule.use[2].loader).toMatch('ts-loader')
19+
expect(rule.use[0].loader).toMatch(require.resolve('cache-loader'))
20+
expect(rule.use[1].loader).toMatch(require.resolve('babel-loader'))
21+
expect(rule.use[2].loader).toMatch(require.resolve('ts-loader'))
2222
})
2323

2424
const creatorOptions = {

packages/@vue/cli-plugin-typescript/index.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ module.exports = (api, projectOptions) => {
2828
}
2929

3030
addLoader({
31-
loader: 'cache-loader',
31+
loader: require.resolve('cache-loader'),
3232
options: api.genCacheConfig('ts-loader', {
3333
'ts-loader': require('ts-loader/package.json').version,
3434
'typescript': require('typescript/package.json').version,
@@ -38,7 +38,7 @@ module.exports = (api, projectOptions) => {
3838

3939
if (useThreads) {
4040
addLoader({
41-
loader: 'thread-loader',
41+
loader: require.resolve('thread-loader'),
4242
options:
4343
typeof projectOptions.parallel === 'number'
4444
? { workers: projectOptions.parallel }
@@ -48,11 +48,15 @@ module.exports = (api, projectOptions) => {
4848

4949
if (api.hasPlugin('babel')) {
5050
addLoader({
51-
loader: 'babel-loader'
51+
// TODO: I guess the intent is to require the `babel-loader` provided by the Babel vue
52+
// plugin, but that means we now rely on the hoisting. It should instead be queried
53+
// against the plugin itself, or through a peer dependency.
54+
// eslint-disable-next-line node/no-extraneous-require
55+
loader: require.resolve('babel-loader')
5256
})
5357
}
5458
addLoader({
55-
loader: 'ts-loader',
59+
loader: require.resolve('ts-loader'),
5660
options: {
5761
transpileOnly: true,
5862
appendTsSuffixTo: ['\\.vue$'],
@@ -61,7 +65,7 @@ module.exports = (api, projectOptions) => {
6165
}
6266
})
6367
// make sure to append TSX suffix
64-
tsxRule.use('ts-loader').loader('ts-loader').tap(options => {
68+
tsxRule.use('ts-loader').loader(require.resolve('ts-loader')).tap(options => {
6569
options = Object.assign({}, options)
6670
delete options.appendTsSuffixTo
6771
options.appendTsxSuffixTo = ['\\.vue$']

packages/@vue/cli-plugin-typescript/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
"dependencies": {
2626
"@types/webpack-env": "^1.13.9",
2727
"@vue/cli-shared-utils": "^4.0.5",
28+
"cache-loader": "^4.1.0",
2829
"fork-ts-checker-webpack-plugin": "^1.5.1",
2930
"globby": "^9.2.0",
31+
"thread-loader": "^2.1.3",
3032
"ts-loader": "^6.2.0",
3133
"tslint": "^5.16.0",
3234
"webpack": "^4.0.0",

packages/@vue/cli-service/__tests__/css.spec.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ const findLoaders = (config, lang, index) => {
4444
if (!rule) {
4545
throw new Error(`rule not found for ${lang}`)
4646
}
47-
return rule.use.map(({ loader }) => loader.replace(/-loader$/, ''))
47+
return rule.use.map(({ loader }) => {
48+
const match = loader.match(/([^\\/]+)-loader/)
49+
return match ? match[1] : loader
50+
})
4851
}
4952

5053
const findOptions = (config, lang, _loader, index) => {

packages/@vue/cli-service/lib/config/base.js

+17-9
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ module.exports = (api, options) => {
7777
.rule('vue')
7878
.test(/\.vue$/)
7979
.use('cache-loader')
80-
.loader('cache-loader')
80+
.loader(require.resolve('cache-loader'))
8181
.options(vueLoaderCacheConfig)
8282
.end()
8383
.use('vue-loader')
84-
.loader('vue-loader')
84+
.loader(require.resolve('vue-loader'))
8585
.options(Object.assign({
8686
compilerOptions: {
8787
whitespace: 'condense'
@@ -98,7 +98,7 @@ module.exports = (api, options) => {
9898
.rule('images')
9999
.test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
100100
.use('url-loader')
101-
.loader('url-loader')
101+
.loader(require.resolve('url-loader'))
102102
.options(genUrlLoaderOptions('img'))
103103

104104
// do not base64-inline SVGs.
@@ -107,7 +107,7 @@ module.exports = (api, options) => {
107107
.rule('svg')
108108
.test(/\.(svg)(\?.*)?$/)
109109
.use('file-loader')
110-
.loader('file-loader')
110+
.loader(require.resolve('file-loader'))
111111
.options({
112112
name: genAssetSubPath('img')
113113
})
@@ -116,33 +116,41 @@ module.exports = (api, options) => {
116116
.rule('media')
117117
.test(/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/)
118118
.use('url-loader')
119-
.loader('url-loader')
119+
.loader(require.resolve('url-loader'))
120120
.options(genUrlLoaderOptions('media'))
121121

122122
webpackConfig.module
123123
.rule('fonts')
124124
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i)
125125
.use('url-loader')
126-
.loader('url-loader')
126+
.loader(require.resolve('url-loader'))
127127
.options(genUrlLoaderOptions('fonts'))
128128

129129
// Other common pre-processors ---------------------------------------------
130130

131+
const maybeResolve = name => {
132+
try {
133+
return require.resolve(name)
134+
} catch (error) {
135+
return name
136+
}
137+
}
138+
131139
webpackConfig.module
132140
.rule('pug')
133141
.test(/\.pug$/)
134142
.oneOf('pug-vue')
135143
.resourceQuery(/vue/)
136144
.use('pug-plain-loader')
137-
.loader('pug-plain-loader')
145+
.loader(maybeResolve('pug-plain-loader'))
138146
.end()
139147
.end()
140148
.oneOf('pug-template')
141149
.use('raw')
142-
.loader('raw-loader')
150+
.loader(maybeResolve('raw-loader'))
143151
.end()
144152
.use('pug-plain-loader')
145-
.loader('pug-plain-loader')
153+
.loader(maybeResolve('pug-plain-loader'))
146154
.end()
147155
.end()
148156

packages/@vue/cli-service/lib/config/css.js

+12-5
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ module.exports = (api, rootOptions) => {
128128
} else {
129129
rule
130130
.use('vue-style-loader')
131-
.loader('vue-style-loader')
131+
.loader(require.resolve('vue-style-loader'))
132132
.options({
133133
sourceMap,
134134
shadowMode
@@ -155,13 +155,13 @@ module.exports = (api, rootOptions) => {
155155

156156
rule
157157
.use('css-loader')
158-
.loader('css-loader')
158+
.loader(require.resolve('css-loader'))
159159
.options(cssLoaderOptions)
160160

161161
if (needInlineMinification) {
162162
rule
163163
.use('cssnano')
164-
.loader('postcss-loader')
164+
.loader(require.resolve('postcss-loader'))
165165
.options({
166166
sourceMap,
167167
plugins: [require('cssnano')(cssnanoOptions)]
@@ -171,14 +171,21 @@ module.exports = (api, rootOptions) => {
171171
if (hasPostCSSConfig) {
172172
rule
173173
.use('postcss-loader')
174-
.loader('postcss-loader')
174+
.loader(require.resolve('postcss-loader'))
175175
.options(Object.assign({ sourceMap }, loaderOptions.postcss))
176176
}
177177

178178
if (loader) {
179+
let resolvedLoader
180+
try {
181+
resolvedLoader = require.resolve(loader)
182+
} catch (error) {
183+
resolvedLoader = loader
184+
}
185+
179186
rule
180187
.use(loader)
181-
.loader(loader)
188+
.loader(resolvedLoader)
182189
.options(Object.assign({ sourceMap }, options))
183190
}
184191
}

packages/@vue/cli-service/package.json

+18
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"thread-loader": "^2.1.3",
7676
"url-loader": "^2.2.0",
7777
"vue-loader": "^15.7.0",
78+
"vue-style-loader": "^4.1.0",
7879
"webpack": "^4.0.0",
7980
"webpack-bundle-analyzer": "^3.6.0",
8081
"webpack-chain": "^6.0.0",
@@ -84,6 +85,23 @@
8485
"peerDependencies": {
8586
"vue-template-compiler": "^2.0.0"
8687
},
88+
"peerDependenciesMeta": {
89+
"less-loader": {
90+
"optional": true
91+
},
92+
"pug-plain-loader": {
93+
"optional": true
94+
},
95+
"raw-loader": {
96+
"optional": true
97+
},
98+
"sass-loader": {
99+
"optional": true
100+
},
101+
"stylus-loader": {
102+
"optional": true
103+
}
104+
},
87105
"devDependencies": {
88106
"fibers": ">= 3.1.1 <5.0.0",
89107
"sass": "^1.19.0",

packages/@vue/cli-ui/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ exports.clientAddonConfig = function ({ id, port = 8042 }) {
2323
.rule('gql')
2424
.test(/\.(gql|graphql)$/)
2525
.use('gql-loader')
26-
.loader('graphql-tag/loader')
26+
.loader(require.resolve('graphql-tag/loader'))
2727
.end()
2828
},
2929
devServer: {

0 commit comments

Comments
 (0)