refactor(cli): default to .js for eslintrc and postcssrc

close #994
This commit is contained in:
Evan You
2018-04-27 12:45:45 -04:00
parent 23480ae8f5
commit 9cfafea328
10 changed files with 51 additions and 30 deletions

View File

@@ -73,7 +73,7 @@ module.exports = (api, { config, lintOn = [] }) => {
}
}
api.render(files => {
files['tests/unit/.eslintrc'] = JSON.stringify(config, null, 2)
files['tests/unit/.eslintrc.js'] = api.genJSConfig(config)
})
} else if (api.hasPlugin('unit-jest')) {
const config = {
@@ -85,7 +85,7 @@ module.exports = (api, { config, lintOn = [] }) => {
}
}
api.render(files => {
files['tests/unit/.eslintrc'] = JSON.stringify(config, null, 2)
files['tests/unit/.eslintrc.js'] = api.genJSConfig(config)
})
}

View File

@@ -112,7 +112,7 @@ module.exports = (api, {
// delete all js files that have a ts file of the same name
// and simply rename other js files to ts
const jsRE = /\.js$/
const excludeRE = /^tests\/e2e\/|\.config\.js$/
const excludeRE = /^tests\/e2e\/|(\.config|rc)\.js$/
const convertLintFlags = require('../lib/convertLintFlags')
api.postProcessFiles(files => {
for (const file in files) {

View File

@@ -18,7 +18,7 @@ test('base', async () => {
expect(pkg.scripts.test).toBeTruthy()
expect(pkg.devDependencies).toHaveProperty('@vue/test-utils')
expect(pkg.devDependencies).toHaveProperty('babel-jest')
expect(files['tests/unit/.eslintrc']).toMatch('"jest": true')
expect(files['tests/unit/.eslintrc.js']).toMatch('jest: true')
const spec = files['tests/unit/HelloWorld.spec.js']
expect(spec).toMatch(`expect(wrapper.text()).toMatch(msg)`)

View File

@@ -65,12 +65,12 @@ module.exports = api => {
if (api.hasPlugin('eslint')) {
api.render(files => {
files['tests/unit/.eslintrc'] = JSON.stringify({
files['tests/unit/.eslintrc.js'] = api.genJSConfig({
env: { jest: true },
rules: {
'import/no-extraneous-dependencies': 'off'
}
}, null, 2)
})
})
}
}

View File

@@ -17,7 +17,7 @@ test('base', async () => {
expect(pkg.scripts.test).toBeTruthy()
expect(pkg.devDependencies).toHaveProperty('@vue/test-utils')
expect(files['tests/unit/.eslintrc']).toMatch('"mocha": true')
expect(files['tests/unit/.eslintrc.js']).toMatch('mocha: true')
const spec = files['tests/unit/HelloWorld.spec.js']
expect(spec).toMatch(`import { expect } from 'chai'`)

View File

@@ -15,12 +15,12 @@ module.exports = api => {
if (api.hasPlugin('eslint')) {
api.render(files => {
files['tests/unit/.eslintrc'] = JSON.stringify({
files['tests/unit/.eslintrc.js'] = api.genJSConfig({
env: { mocha: true },
rules: {
'import/no-extraneous-dependencies': 'off'
}
}, null, 2)
})
})
}
}

View File

@@ -4,6 +4,7 @@ const fs = require('fs')
const path = require('path')
const Generator = require('../lib/Generator')
const { logs } = require('@vue/cli-shared-utils')
const stringifyJS = require('javascript-stringify')
// prepare template fixtures
const mkdirp = require('mkdirp')
@@ -327,7 +328,7 @@ test('api: resolve', () => {
test('extract config files', async () => {
const configs = {
vue: {
lintOnSave: true
lintOnSave: false
},
babel: {
presets: ['@vue/app']
@@ -357,9 +358,10 @@ test('extract config files', async () => {
})
const json = v => JSON.stringify(v, null, 2)
expect(fs.readFileSync('/vue.config.js', 'utf-8')).toMatch('module.exports = {\n lintOnSave: true\n}')
const js = v => `module.exports = ${stringifyJS(v, null, 2)}`
expect(fs.readFileSync('/vue.config.js', 'utf-8')).toMatch(js(configs.vue))
expect(fs.readFileSync('/.babelrc', 'utf-8')).toMatch(json(configs.babel))
expect(fs.readFileSync('/.postcssrc', 'utf-8')).toMatch(json(configs.postcss))
expect(fs.readFileSync('/.eslintrc', 'utf-8')).toMatch(json(configs.eslintConfig))
expect(fs.readFileSync('/jest.config.js', 'utf-8')).toMatch(`module.exports = {\n foo: 'bar'\n}`)
expect(fs.readFileSync('/.postcssrc.js', 'utf-8')).toMatch(js(configs.postcss))
expect(fs.readFileSync('/.eslintrc.js', 'utf-8')).toMatch(js(configs.eslintConfig))
expect(fs.readFileSync('/jest.config.js', 'utf-8')).toMatch(js(configs.jest))
})

View File

@@ -4,6 +4,8 @@ jest.mock('inquirer')
const invoke = require('../lib/invoke')
const { expectPrompts } = require('inquirer')
const create = require('@vue/cli-test-utils/createTestProject')
const stringifyJS = require('javascript-stringify')
const toJS = v => `module.exports = ${stringifyJS(v, null, 2)}`
async function createAndInstall (name) {
const project = await create(name, {
@@ -26,11 +28,11 @@ async function assertUpdates (project) {
'pre-commit': 'lint-staged'
})
const eslintrc = JSON.parse(await project.read('.eslintrc'))
expect(eslintrc).toEqual({
const eslintrc = await project.read('.eslintrc.js')
expect(eslintrc).toEqual(toJS({
root: true,
extends: ['plugin:vue/essential', '@vue/airbnb']
})
}))
const lintedMain = await project.read('src/main.js')
expect(lintedMain).toMatch(';') // should've been linted in post-generate hook
@@ -78,11 +80,11 @@ test('invoke with existing files', async () => {
// mock existing vue.config.js
await project.write('vue.config.js', `module.exports = { lintOnSave: true }`)
const eslintrc = JSON.parse(await project.read('.eslintrc'))
expect(eslintrc).toEqual({
const eslintrc = await project.read('.eslintrc.js')
expect(eslintrc).toEqual(toJS({
root: true,
extends: ['plugin:vue/essential', 'eslint:recommended']
})
}))
await project.run(`${require.resolve('../bin/vue')} invoke eslint --config airbnb --lintOn commit`)
@@ -104,13 +106,13 @@ test('invoke with existing files (yaml)', async () => {
pkg.devDependencies['@vue/cli-plugin-eslint'] = '*'
await project.write('package.json', JSON.stringify(pkg, null, 2))
const eslintrc = JSON.parse(await project.read('.eslintrc'))
expect(eslintrc).toEqual({
const eslintrc = await project.read('.eslintrc.js')
expect(eslintrc).toEqual(toJS({
root: true,
extends: ['plugin:vue/essential', 'eslint:recommended']
})
}))
await project.rm(`.eslintrc`)
await project.rm(`.eslintrc.js`)
await project.write(`.eslintrc.yml`, `
root: true
extends:

View File

@@ -7,6 +7,7 @@ const resolve = require('resolve')
const isBinary = require('isbinaryfile')
const yaml = require('yaml-front-matter')
const mergeDeps = require('./util/mergeDeps')
const stringifyJS = require('javascript-stringify')
const { getPluginLink, toShortPluginId } = require('@vue/cli-shared-utils')
const isString = val => typeof val === 'string'
@@ -191,6 +192,13 @@ class GeneratorAPI {
exitLog (msg, type = 'log') {
this.generator.exitLogs.push({ id: this.id, msg, type })
}
/**
* convenience method for generating a js config file from json
*/
genJSConfig (value) {
return `module.exports = ${stringifyJS(value, null, 2)}`
}
}
function extractCallDir () {

View File

@@ -35,11 +35,20 @@ function makeJSONTransform (filename) {
}
}
function makeMutliExtensionJSONTransform (filename) {
function makeMutliExtensionJSONTransform (filename, preferJS) {
return function transformToMultiExtensions (value, checkExisting, context) {
if (!checkExisting) {
return makeJSONTransform(filename)(value, checkExisting, context)
function defaultTransform () {
if (preferJS) {
return makeJSTransform(`${filename}.js`)(value, false, context)
} else {
return makeJSONTransform(filename)(value, false, context)
}
}
if (!checkExisting) {
return defaultTransform()
}
const absolutePath = path.resolve(context, filename)
if (fs.existsSync(absolutePath)) {
return makeJSONTransform(filename)(value, checkExisting, context)
@@ -52,7 +61,7 @@ function makeMutliExtensionJSONTransform (filename) {
} else if (fs.existsSync(`${absolutePath}.yml`)) {
return transformYAML(value, `${filename}.yml`, fs.readFileSync(`${absolutePath}.yml`, 'utf-8'))
} else {
return makeJSONTransform(filename)(value, false, context)
return defaultTransform()
}
}
}
@@ -69,7 +78,7 @@ function transformYAML (value, filename, source) {
module.exports = {
vue: makeJSTransform('vue.config.js'),
babel: makeJSONTransform('.babelrc'),
postcss: makeMutliExtensionJSONTransform('.postcssrc'),
eslintConfig: makeMutliExtensionJSONTransform('.eslintrc'),
postcss: makeMutliExtensionJSONTransform('.postcssrc', true),
eslintConfig: makeMutliExtensionJSONTransform('.eslintrc', true),
jest: makeJSTransform('jest.config.js')
}