Skip to content

Commit

Permalink
fix(eslint): ensure all config values are contained in config file
Browse files Browse the repository at this point in the history
close #1006, close #1313
  • Loading branch information
yyx990803 committed May 18, 2018
1 parent a67f34a commit 83f5f4f
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 47 deletions.
45 changes: 29 additions & 16 deletions packages/@vue/cli-plugin-eslint/__tests__/eslintGenerator.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ test('base', async () => {
})

expect(pkg.scripts.lint).toBeTruthy()
expect(pkg.eslintConfig).toEqual({
root: true,
extends: ['plugin:vue/essential', 'eslint:recommended']
expect(pkg.eslintConfig.extends).toEqual([
'plugin:vue/essential', 'eslint:recommended'
])
expect(pkg.eslintConfig.parserOptions).toEqual({
parser: 'babel-eslint'
})
})

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

expect(pkg.scripts.lint).toBeTruthy()
expect(pkg.eslintConfig).toEqual({
root: true,
extends: ['plugin:vue/essential', '@vue/airbnb']
expect(pkg.eslintConfig.extends).toEqual([
'plugin:vue/essential',
'@vue/airbnb'
])
expect(pkg.eslintConfig.parserOptions).toEqual({
parser: 'babel-eslint'
})
expect(pkg.devDependencies).toHaveProperty('@vue/eslint-config-airbnb')
})
Expand All @@ -41,9 +46,12 @@ test('standard', async () => {
})

expect(pkg.scripts.lint).toBeTruthy()
expect(pkg.eslintConfig).toEqual({
root: true,
extends: ['plugin:vue/essential', '@vue/standard']
expect(pkg.eslintConfig.extends).toEqual([
'plugin:vue/essential',
'@vue/standard'
])
expect(pkg.eslintConfig.parserOptions).toEqual({
parser: 'babel-eslint'
})
expect(pkg.devDependencies).toHaveProperty('@vue/eslint-config-standard')
})
Expand All @@ -58,9 +66,12 @@ test('prettier', async () => {
})

expect(pkg.scripts.lint).toBeTruthy()
expect(pkg.eslintConfig).toEqual({
root: true,
extends: ['plugin:vue/essential', '@vue/prettier']
expect(pkg.eslintConfig.extends).toEqual([
'plugin:vue/essential',
'@vue/prettier'
])
expect(pkg.eslintConfig.parserOptions).toEqual({
parser: 'babel-eslint'
})
expect(pkg.devDependencies).toHaveProperty('@vue/eslint-config-prettier')
})
Expand All @@ -82,10 +93,12 @@ test('typescript', async () => {
])

expect(pkg.scripts.lint).toBeTruthy()
expect(pkg.eslintConfig).toEqual({
root: true,
extends: ['plugin:vue/essential', '@vue/prettier', '@vue/typescript']
})
expect(pkg.eslintConfig.extends).toEqual([
'plugin:vue/essential',
'@vue/prettier',
'@vue/typescript'
])
expect(pkg.eslintConfig).not.toHaveProperty('parserOptions')
expect(pkg.devDependencies).toHaveProperty('@vue/eslint-config-prettier')
expect(pkg.devDependencies).toHaveProperty('@vue/eslint-config-typescript')
})
Expand Down
36 changes: 23 additions & 13 deletions packages/@vue/cli-plugin-eslint/eslintOptions.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
module.exports = api => {
const options = {
extensions: ['.js', '.vue'],
envs: ['node'],
exports.config = api => {
const config = {
root: true,
env: { node: true },
extends: ['plugin:vue/essential'],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
'no-console': makeJSOnlyValue(`process.env.NODE_ENV === 'production' ? 'error' : 'off'`),
'no-debugger': makeJSOnlyValue(`process.env.NODE_ENV === 'production' ? 'error' : 'off'`)
}
}

if (api.hasPlugin('typescript')) {
options.extensions.push('.ts')
} else {
options.parserOptions = {
parser: require.resolve('babel-eslint')
if (!api.hasPlugin('typescript')) {
config.parserOptions = {
parser: 'babel-eslint'
}
}
return config
}

return options
// __expression is a special flag that allows us to customize stringification
// output when extracting configs into standalone files
function makeJSOnlyValue (str) {
const fn = () => {}
fn.__expression = str
return fn
}

const baseExtensions = ['.js', '.jsx', '.vue']
exports.extensions = api => api.hasPlugin('typescript')
? baseExtensions.concat('.ts', '.tsx')
: baseExtensions
17 changes: 8 additions & 9 deletions packages/@vue/cli-plugin-eslint/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,39 @@ module.exports = (api, { config, lintOn = [] }) => {
lintOn = lintOn.split(',')
}

const eslintConfig = require('./eslintOptions').config(api)

const pkg = {
scripts: {
lint: 'vue-cli-service lint'
},
eslintConfig: {
root: true,
extends: ['plugin:vue/essential']
},
eslintConfig,
devDependencies: {}
}

if (config === 'airbnb') {
pkg.eslintConfig.extends.push('@vue/airbnb')
eslintConfig.extends.push('@vue/airbnb')
Object.assign(pkg.devDependencies, {
'@vue/eslint-config-airbnb': '^3.0.0-beta.10'
})
} else if (config === 'standard') {
pkg.eslintConfig.extends.push('@vue/standard')
eslintConfig.extends.push('@vue/standard')
Object.assign(pkg.devDependencies, {
'@vue/eslint-config-standard': '^3.0.0-beta.10'
})
} else if (config === 'prettier') {
pkg.eslintConfig.extends.push('@vue/prettier')
eslintConfig.extends.push('@vue/prettier')
Object.assign(pkg.devDependencies, {
'@vue/eslint-config-prettier': '^3.0.0-beta.10'
})
} else {
// default
pkg.eslintConfig.extends.push('eslint:recommended')
eslintConfig.extends.push('eslint:recommended')
}

// typescript support
if (api.hasPlugin('typescript')) {
pkg.eslintConfig.extends.push('@vue/typescript')
eslintConfig.extends.push('@vue/typescript')
Object.assign(pkg.devDependencies, {
'@vue/eslint-config-typescript': '^3.0.0-beta.10'
})
Expand Down
7 changes: 4 additions & 3 deletions packages/@vue/cli-plugin-eslint/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = (api, { lintOnSave }) => {
if (lintOnSave) {
const options = require('./eslintOptions')(api)
const extensions = require('./eslintOptions').extensions(api)
api.chainWebpack(webpackConfig => {
webpackConfig.module
.rule('eslint')
Expand All @@ -12,10 +12,11 @@ module.exports = (api, { lintOnSave }) => {
.test(/\.(vue|(j|t)sx?)$/)
.use('eslint-loader')
.loader('eslint-loader')
.options(Object.assign(options, {
.options({
extensions,
emitWarning: lintOnSave !== 'error',
formatter: require('eslint/lib/formatters/codeframe')
}))
})
})
}

Expand Down
11 changes: 6 additions & 5 deletions packages/@vue/cli-plugin-eslint/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ module.exports = function lint (args = {}, api) {
const chalk = require('chalk')
const cwd = api.resolve('.')
const { CLIEngine } = require('eslint')
const options = require('./eslintOptions')(api)
const { log, done } = require('@vue/cli-shared-utils')

const files = args._ && args._.length ? args._ : ['src', 'tests', '*.js']
const extensions = require('./eslintOptions').extensions(api)
const argsConfig = normalizeConfig(args)
const config = Object.assign({}, options, {
const config = Object.assign({
extensions,
fix: true,
cwd
}, argsConfig)
Expand All @@ -36,7 +37,7 @@ module.exports = function lint (args = {}, api) {
if (config.fix) {
CLIEngine.outputFixes(report)
}

const maxErrors = argsConfig.maxErrors || 0
const maxWarnings = typeof argsConfig.maxWarnings === 'number' ? argsConfig.maxWarnings : Infinity
const isErrorsExceeded = report.errorCount > maxErrors
Expand All @@ -63,10 +64,10 @@ module.exports = function lint (args = {}, api) {
}
} else {
console.log(formatter(report.results))
if (isErrorsExceed && typeof argsConfig.maxErrors === 'number') {
if (isErrorsExceeded && typeof argsConfig.maxErrors === 'number') {
log(`Eslint found too many errors (maximum: ${argsConfig.maxErrors}).`)
}
if (isWarningsExceed) {
if (isWarningsExceeded) {
log(`Eslint found too many warnings (maximum: ${argsConfig.maxWarnings}).`)
}
process.exit(1)
Expand Down
11 changes: 10 additions & 1 deletion packages/@vue/cli/lib/util/configTransforms.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
const fs = require('fs')
const path = require('path')
const extendJSConfig = require('./extendJSConfig')
const stringifyJS = require('javascript-stringify')
const stringify = require('javascript-stringify')

function stringifyJS (value) {
return stringify(value, (val, indent, stringify) => {
if (val && val.__expression) {
return val.__expression
}
return stringify(val)
}, 2)
}

function makeJSTransform (filename) {
return function transformToJS (value, checkExisting, context) {
Expand Down

0 comments on commit 83f5f4f

Please sign in to comment.