Skip to content

Commit 83f5f4f

Browse files
committed
fix(eslint): ensure all config values are contained in config file
close #1006, close #1313
1 parent a67f34a commit 83f5f4f

File tree

6 files changed

+80
-47
lines changed

6 files changed

+80
-47
lines changed

packages/@vue/cli-plugin-eslint/__tests__/eslintGenerator.spec.js

+29-16
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ test('base', async () => {
88
})
99

1010
expect(pkg.scripts.lint).toBeTruthy()
11-
expect(pkg.eslintConfig).toEqual({
12-
root: true,
13-
extends: ['plugin:vue/essential', 'eslint:recommended']
11+
expect(pkg.eslintConfig.extends).toEqual([
12+
'plugin:vue/essential', 'eslint:recommended'
13+
])
14+
expect(pkg.eslintConfig.parserOptions).toEqual({
15+
parser: 'babel-eslint'
1416
})
1517
})
1618

@@ -24,9 +26,12 @@ test('airbnb', async () => {
2426
})
2527

2628
expect(pkg.scripts.lint).toBeTruthy()
27-
expect(pkg.eslintConfig).toEqual({
28-
root: true,
29-
extends: ['plugin:vue/essential', '@vue/airbnb']
29+
expect(pkg.eslintConfig.extends).toEqual([
30+
'plugin:vue/essential',
31+
'@vue/airbnb'
32+
])
33+
expect(pkg.eslintConfig.parserOptions).toEqual({
34+
parser: 'babel-eslint'
3035
})
3136
expect(pkg.devDependencies).toHaveProperty('@vue/eslint-config-airbnb')
3237
})
@@ -41,9 +46,12 @@ test('standard', async () => {
4146
})
4247

4348
expect(pkg.scripts.lint).toBeTruthy()
44-
expect(pkg.eslintConfig).toEqual({
45-
root: true,
46-
extends: ['plugin:vue/essential', '@vue/standard']
49+
expect(pkg.eslintConfig.extends).toEqual([
50+
'plugin:vue/essential',
51+
'@vue/standard'
52+
])
53+
expect(pkg.eslintConfig.parserOptions).toEqual({
54+
parser: 'babel-eslint'
4755
})
4856
expect(pkg.devDependencies).toHaveProperty('@vue/eslint-config-standard')
4957
})
@@ -58,9 +66,12 @@ test('prettier', async () => {
5866
})
5967

6068
expect(pkg.scripts.lint).toBeTruthy()
61-
expect(pkg.eslintConfig).toEqual({
62-
root: true,
63-
extends: ['plugin:vue/essential', '@vue/prettier']
69+
expect(pkg.eslintConfig.extends).toEqual([
70+
'plugin:vue/essential',
71+
'@vue/prettier'
72+
])
73+
expect(pkg.eslintConfig.parserOptions).toEqual({
74+
parser: 'babel-eslint'
6475
})
6576
expect(pkg.devDependencies).toHaveProperty('@vue/eslint-config-prettier')
6677
})
@@ -82,10 +93,12 @@ test('typescript', async () => {
8293
])
8394

8495
expect(pkg.scripts.lint).toBeTruthy()
85-
expect(pkg.eslintConfig).toEqual({
86-
root: true,
87-
extends: ['plugin:vue/essential', '@vue/prettier', '@vue/typescript']
88-
})
96+
expect(pkg.eslintConfig.extends).toEqual([
97+
'plugin:vue/essential',
98+
'@vue/prettier',
99+
'@vue/typescript'
100+
])
101+
expect(pkg.eslintConfig).not.toHaveProperty('parserOptions')
89102
expect(pkg.devDependencies).toHaveProperty('@vue/eslint-config-prettier')
90103
expect(pkg.devDependencies).toHaveProperty('@vue/eslint-config-typescript')
91104
})
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
1-
module.exports = api => {
2-
const options = {
3-
extensions: ['.js', '.vue'],
4-
envs: ['node'],
1+
exports.config = api => {
2+
const config = {
3+
root: true,
4+
env: { node: true },
5+
extends: ['plugin:vue/essential'],
56
rules: {
6-
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
7-
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
7+
'no-console': makeJSOnlyValue(`process.env.NODE_ENV === 'production' ? 'error' : 'off'`),
8+
'no-debugger': makeJSOnlyValue(`process.env.NODE_ENV === 'production' ? 'error' : 'off'`)
89
}
910
}
10-
11-
if (api.hasPlugin('typescript')) {
12-
options.extensions.push('.ts')
13-
} else {
14-
options.parserOptions = {
15-
parser: require.resolve('babel-eslint')
11+
if (!api.hasPlugin('typescript')) {
12+
config.parserOptions = {
13+
parser: 'babel-eslint'
1614
}
1715
}
16+
return config
17+
}
1818

19-
return options
19+
// __expression is a special flag that allows us to customize stringification
20+
// output when extracting configs into standalone files
21+
function makeJSOnlyValue (str) {
22+
const fn = () => {}
23+
fn.__expression = str
24+
return fn
2025
}
26+
27+
const baseExtensions = ['.js', '.jsx', '.vue']
28+
exports.extensions = api => api.hasPlugin('typescript')
29+
? baseExtensions.concat('.ts', '.tsx')
30+
: baseExtensions

packages/@vue/cli-plugin-eslint/generator.js

+8-9
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,39 @@ module.exports = (api, { config, lintOn = [] }) => {
33
lintOn = lintOn.split(',')
44
}
55

6+
const eslintConfig = require('./eslintOptions').config(api)
7+
68
const pkg = {
79
scripts: {
810
lint: 'vue-cli-service lint'
911
},
10-
eslintConfig: {
11-
root: true,
12-
extends: ['plugin:vue/essential']
13-
},
12+
eslintConfig,
1413
devDependencies: {}
1514
}
1615

1716
if (config === 'airbnb') {
18-
pkg.eslintConfig.extends.push('@vue/airbnb')
17+
eslintConfig.extends.push('@vue/airbnb')
1918
Object.assign(pkg.devDependencies, {
2019
'@vue/eslint-config-airbnb': '^3.0.0-beta.10'
2120
})
2221
} else if (config === 'standard') {
23-
pkg.eslintConfig.extends.push('@vue/standard')
22+
eslintConfig.extends.push('@vue/standard')
2423
Object.assign(pkg.devDependencies, {
2524
'@vue/eslint-config-standard': '^3.0.0-beta.10'
2625
})
2726
} else if (config === 'prettier') {
28-
pkg.eslintConfig.extends.push('@vue/prettier')
27+
eslintConfig.extends.push('@vue/prettier')
2928
Object.assign(pkg.devDependencies, {
3029
'@vue/eslint-config-prettier': '^3.0.0-beta.10'
3130
})
3231
} else {
3332
// default
34-
pkg.eslintConfig.extends.push('eslint:recommended')
33+
eslintConfig.extends.push('eslint:recommended')
3534
}
3635

3736
// typescript support
3837
if (api.hasPlugin('typescript')) {
39-
pkg.eslintConfig.extends.push('@vue/typescript')
38+
eslintConfig.extends.push('@vue/typescript')
4039
Object.assign(pkg.devDependencies, {
4140
'@vue/eslint-config-typescript': '^3.0.0-beta.10'
4241
})

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module.exports = (api, { lintOnSave }) => {
22
if (lintOnSave) {
3-
const options = require('./eslintOptions')(api)
3+
const extensions = require('./eslintOptions').extensions(api)
44
api.chainWebpack(webpackConfig => {
55
webpackConfig.module
66
.rule('eslint')
@@ -12,10 +12,11 @@ module.exports = (api, { lintOnSave }) => {
1212
.test(/\.(vue|(j|t)sx?)$/)
1313
.use('eslint-loader')
1414
.loader('eslint-loader')
15-
.options(Object.assign(options, {
15+
.options({
16+
extensions,
1617
emitWarning: lintOnSave !== 'error',
1718
formatter: require('eslint/lib/formatters/codeframe')
18-
}))
19+
})
1920
})
2021
}
2122

packages/@vue/cli-plugin-eslint/lint.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ module.exports = function lint (args = {}, api) {
2020
const chalk = require('chalk')
2121
const cwd = api.resolve('.')
2222
const { CLIEngine } = require('eslint')
23-
const options = require('./eslintOptions')(api)
2423
const { log, done } = require('@vue/cli-shared-utils')
2524

2625
const files = args._ && args._.length ? args._ : ['src', 'tests', '*.js']
26+
const extensions = require('./eslintOptions').extensions(api)
2727
const argsConfig = normalizeConfig(args)
28-
const config = Object.assign({}, options, {
28+
const config = Object.assign({
29+
extensions,
2930
fix: true,
3031
cwd
3132
}, argsConfig)
@@ -36,7 +37,7 @@ module.exports = function lint (args = {}, api) {
3637
if (config.fix) {
3738
CLIEngine.outputFixes(report)
3839
}
39-
40+
4041
const maxErrors = argsConfig.maxErrors || 0
4142
const maxWarnings = typeof argsConfig.maxWarnings === 'number' ? argsConfig.maxWarnings : Infinity
4243
const isErrorsExceeded = report.errorCount > maxErrors
@@ -63,10 +64,10 @@ module.exports = function lint (args = {}, api) {
6364
}
6465
} else {
6566
console.log(formatter(report.results))
66-
if (isErrorsExceed && typeof argsConfig.maxErrors === 'number') {
67+
if (isErrorsExceeded && typeof argsConfig.maxErrors === 'number') {
6768
log(`Eslint found too many errors (maximum: ${argsConfig.maxErrors}).`)
6869
}
69-
if (isWarningsExceed) {
70+
if (isWarningsExceeded) {
7071
log(`Eslint found too many warnings (maximum: ${argsConfig.maxWarnings}).`)
7172
}
7273
process.exit(1)

packages/@vue/cli/lib/util/configTransforms.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
const fs = require('fs')
22
const path = require('path')
33
const extendJSConfig = require('./extendJSConfig')
4-
const stringifyJS = require('javascript-stringify')
4+
const stringify = require('javascript-stringify')
5+
6+
function stringifyJS (value) {
7+
return stringify(value, (val, indent, stringify) => {
8+
if (val && val.__expression) {
9+
return val.__expression
10+
}
11+
return stringify(val)
12+
}, 2)
13+
}
514

615
function makeJSTransform (filename) {
716
return function transformToJS (value, checkExisting, context) {

0 commit comments

Comments
 (0)