Skip to content

Commit 4225c30

Browse files
authored
feat: support vue.config.cjs (#5293)
* chore: Update yarn.lock * feat: support vue.config.cjs * fix: vue.config.js prior than cjs * chore: merge upstream
1 parent d8afaa0 commit 4225c30

File tree

5 files changed

+89
-22
lines changed

5 files changed

+89
-22
lines changed

Diff for: packages/@vue/cli-service/__tests__/Service.spec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ test('env loading for custom mode', () => {
6060
test('loading plugins from package.json', () => {
6161
mockPkg({
6262
devDependencies: {
63-
'bar': '^1.0.0',
63+
bar: '^1.0.0',
6464
'@vue/cli-plugin-babel': '^4.2.0',
6565
'vue-cli-plugin-foo': '^1.0.0'
6666
}
@@ -183,7 +183,7 @@ test('api: --skip-plugins', () => {
183183
id: 'test-command',
184184
apply: api => {
185185
api.registerCommand('foo', _args => {
186-
return
186+
187187
})
188188
}
189189
},
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const { join } = require('path')
2+
const Service = require('../lib/Service')
3+
4+
const mockDir = join(__dirname, 'mockESM')
5+
const configPath = join(mockDir, 'vue.config.cjs')
6+
7+
const createService = () => {
8+
const service = new Service(mockDir, {
9+
plugins: [],
10+
useBuiltIn: false
11+
})
12+
service.init()
13+
return service
14+
}
15+
16+
// vue.config.cjs has higher priority
17+
18+
test('load project options from package.json', async () => {
19+
const service = createService()
20+
expect(service.projectOptions.lintOnSave).toBe('default')
21+
})
22+
23+
test('load project options from vue.config.cjs', async () => {
24+
jest.mock(configPath, () => ({ lintOnSave: true }), { virtual: true })
25+
const service = createService()
26+
expect(service.projectOptions.lintOnSave).toBe(true)
27+
})
28+
29+
test('load project options from vue.config.cjs as a function', async () => {
30+
jest.mock(configPath, () => function () { return { lintOnSave: true } }, { virtual: true })
31+
const service = createService()
32+
expect(service.projectOptions.lintOnSave).toBe(true)
33+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "module",
3+
"vue": {
4+
"lintOnSave": "default"
5+
}
6+
}

Diff for: packages/@vue/cli-service/lib/Service.js

+41-13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ const { chalk, warn, error, isPlugin, resolvePluginId, loadModule, resolvePkg }
1010

1111
const { defaults, validate } = require('./options')
1212

13+
const loadConfig = configPath => {
14+
let fileConfig = require(configPath)
15+
16+
if (typeof fileConfig === 'function') {
17+
fileConfig = fileConfig()
18+
}
19+
20+
if (!fileConfig || typeof fileConfig !== 'object') {
21+
error(
22+
`Error loading ${chalk.bold('vue.config.js')}: should export an object or a function that returns object.`
23+
)
24+
fileConfig = null
25+
}
26+
return fileConfig
27+
}
28+
1329
module.exports = class Service {
1430
constructor (context, { plugins, pkg, inlineOptions, useBuiltIn } = {}) {
1531
process.VUE_CLI_SERVICE = this
@@ -299,31 +315,43 @@ module.exports = class Service {
299315

300316
loadUserOptions () {
301317
// vue.config.js
318+
// vue.config.cjs
302319
let fileConfig, pkgConfig, resolved, resolvedFrom
320+
const esm = this.pkg.type && this.pkg.type === 'module'
321+
const jsConfigPath = path.resolve(this.context, 'vue.config.js')
322+
const cjsConfigPath = path.resolve(this.context, 'vue.config.cjs')
303323
const configPath = (
304324
process.env.VUE_CLI_SERVICE_CONFIG_PATH ||
305-
path.resolve(this.context, 'vue.config.js')
325+
jsConfigPath
306326
)
307-
try {
308-
fileConfig = require(configPath)
309-
310-
if (typeof fileConfig === 'function') {
311-
fileConfig = fileConfig()
312-
}
313327

314-
if (!fileConfig || typeof fileConfig !== 'object') {
315-
error(
316-
`Error loading ${chalk.bold('vue.config.js')}: should export an object or a function that returns object.`
317-
)
318-
fileConfig = null
319-
}
328+
try {
329+
fileConfig = loadConfig(configPath)
320330
} catch (e) {
321331
if (e.code !== 'MODULE_NOT_FOUND') {
332+
if (e.code === 'ERR_REQUIRE_ESM') {
333+
warn(`Rename ${chalk.bold('vue.config.js')} to ${chalk.bold('vue.config.cjs')} when ECMAScript modules is enabled`)
334+
}
322335
error(`Error loading ${chalk.bold('vue.config.js')}:`)
323336
throw e
324337
}
325338
}
326339

340+
// vue.config.js not found, esm enabled, no env set
341+
if (!fileConfig && esm && !process.env.VUE_CLI_SERVICE_CONFIG_PATH) {
342+
try {
343+
fileConfig = loadConfig(cjsConfigPath)
344+
} catch (e) {
345+
if (e.code !== 'MODULE_NOT_FOUND') {
346+
error(`Error loading ${chalk.bold('vue.config.cjs')}:`)
347+
throw e
348+
}
349+
}
350+
if (fileConfig) {
351+
warn(`ECMAScript modules is detected, config loaded from ${chalk.bold('vue.config.cjs')}`)
352+
}
353+
}
354+
327355
// package.vue
328356
pkgConfig = this.pkg.vue
329357
if (pkgConfig && typeof pkgConfig !== 'object') {

Diff for: yarn.lock

+7-7
Original file line numberDiff line numberDiff line change
@@ -5112,7 +5112,7 @@ cheerio@^1.0.0-rc.2:
51125112
lodash "^4.15.0"
51135113
parse5 "^3.0.1"
51145114

5115-
"chokidar@>=2.0.0 <4.0.0":
5115+
"chokidar@>=2.0.0 <4.0.0", chokidar@^3.3.0:
51165116
version "3.3.1"
51175117
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450"
51185118
integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==
@@ -5127,7 +5127,7 @@ cheerio@^1.0.0-rc.2:
51275127
optionalDependencies:
51285128
fsevents "~2.1.2"
51295129

5130-
chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.3, chokidar@^2.0.4, chokidar@^2.1.8:
5130+
chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.3, chokidar@^2.1.8:
51315131
version "2.1.8"
51325132
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
51335133
integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==
@@ -8352,14 +8352,14 @@ forever-agent@~0.6.1:
83528352
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
83538353
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
83548354

8355-
fork-ts-checker-webpack-plugin@^1.5.1:
8356-
version "1.6.0"
8357-
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-1.6.0.tgz#a81fd1c6bf5258fa5318cf3e9a7e9bac006f7917"
8358-
integrity sha512-vqOY5gakcoon2s12V7MMe01OPwfgqulUWFzm+geQaPPOBKjW1I7aqqoBVlU0ECn97liMB0ECs16pRdIGe9qdRw==
8355+
fork-ts-checker-webpack-plugin@^3.1.1:
8356+
version "3.1.1"
8357+
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz#a1642c0d3e65f50c2cc1742e9c0a80f441f86b19"
8358+
integrity sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==
83598359
dependencies:
83608360
babel-code-frame "^6.22.0"
83618361
chalk "^2.4.1"
8362-
chokidar "^2.0.4"
8362+
chokidar "^3.3.0"
83638363
micromatch "^3.1.10"
83648364
minimatch "^3.0.4"
83658365
semver "^5.6.0"

0 commit comments

Comments
 (0)