公司团队目前前端开发人员快速增长,为了保证每个成员代码编写的统一规范,我们都会对代码编写做一些规范。
1.想法
- 使用vscode + vetur + eslint + prettier 实现团队代码风格统一
- eslint 主要负责语法错误检测,并提示
- prettier 主要负责 html/css/less/scss… 的格式化
- vetur 主要负责高亮vue里面template的代码,不做其他操作
2. 使用
- IDE: vsCode
- npm:
eslint
babel-eslint:eslint 支持不同的解析器(parser),而 babel-eslint 就是 babel 为 eslint 开发的语法解析器,使 eslint 可以支持 es6 语法
eslint-plugin-vue:对vue代码语法进行提示
eslint-config-prettier:它会默认关闭所有不必要的或eslint可能与 prettier冲突的规则(本例不打算安装)
eslint-plugin-prettier:它会将 prettier 作为 eslint 的规则来使用,相当于代码不符合 prettier 的标准时,会报一个 eslint 错误,同时也可以通过 eslint --fix 来进行格式化(本例不打算安装)
3.相关配置如下
- .eslintrc.js
/**
*
* 规则说明见 https://cn.eslint.org/docs/rules/
* eslint-plugin-vue 规则见 https://github.com/vuejs/eslint-plugin-vue
*
* "off" 或 0 - 关闭规则
* "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
* "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
*
*/
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
},
extends: ['plugin:vue/recommended', 'eslint:recommended'],
// add your custom rules here
rules: {
'vue/max-attributes-per-line': [2, {
'singleline': 10,
'multiline': {
'max': 1,
'allowFirstLine': false
}
}],
'vue/html-self-closing': 'off',
'vue/singleline-html-element-content-newline': 'off',
'vue/multiline-html-element-content-newline': 'off',
'vue/no-template-shadow': "off",
'vue/name-property-casing': ['error', 'PascalCase'],
'vue/no-v-html': 'off',
'accessor-pairs': 2,
'arrow-spacing': [2, {
'before': true,
'after': true
}],
'block-spacing': [2, 'always'],
'brace-style': [2, '1tbs', {
'allowSingleLine': true
}],
'camelcase': [0, {
'properties': 'always'
}],
'comma-dangle': [2, 'always-multiline'],
'comma-spacing': [2, {
'before': false,
'after': true
}],
'comma-style': [2, 'last'],
'constructor-super': 2,
'curly': [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
'eqeqeq': ["error", "always", {"null": "ignore"}],
'generator-star-spacing': [2, {
'before': true,
'after': true
}],
'handle-callback-err': [2, '^(err|error)$'],
'indent': [2, 2, {
'SwitchCase': 1
}],
'jsx-quotes': [2, 'prefer-single'],
'key-spacing': [2, {
'beforeColon': false,
'afterColon': true
}],
'keyword-spacing': [2, {
'before': true,
'after': true
}],
'new-cap': [2, {
'newIsCap': true,
'capIsNew': false
}],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-console': 'off',
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
'no-eval': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [2, {
'allowLoop': false,
'allowSwitch': false
}],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-multiple-empty-lines': [2, {
'max': 1
}],
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 2,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [2, {
'defaultAssignment': false
}],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [2, {
'vars': 'all',
'args': 'none'
}],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [2, {
'initialized': 'never'
}],
'operator-linebreak': [2, 'after', {
'overrides': {
'?': 'before',
':': 'before'
}
}],
'padded-blocks': [2, 'never'],
'quotes': [2, 'single', {
'avoidEscape': true,
'allowTemplateLiterals': true
}],
'semi': [2, 'always'],
'semi-spacing': [2, {
'before': false,
'after': true
}],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': 0,
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [2, {
'words': true,
'nonwords': false
}],
'spaced-comment': [2, 'always', {
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
}],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
'yoda': [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [2, 'always', {
objectsInObjects: false
}],
'array-bracket-spacing': [2, 'never']
}
}
- .eslintignore
# 忽略build目录下类型为js的文件的语法检查
build/*.js
# 忽略src/assets目录下文件的语法检查
src/assets
# 忽略public目录下文件的语法检查
public
# 忽略当前目录下为js的文件的语法检查
/*.js
- .prettierrc.js
module.exports = {
printWidth: 220,
singleQuote: true, // 使用单引号而不是双引号
semi: true, // 句尾是否加;
proseWrap: 'preserve',
tabWidth: 2,
trailingComma: 'es5', // 在对象或数组最后一个元素后面是否加逗号(在ES5中加尾逗号)
bracketSpacing: true, // 在对象,数组括号与文字之间加空格 "{ foo: bar }"
htmlWhitespaceSensitivity: 'ignore', // > 不乱换行
};
- .prettierignore
.eslintrc.js
/dist/
/node_modules/**
/public/*
- .vscode/settings.json
{
"editor.formatOnSave": true, //保存自动格式化
"editor.defaultFormatter": "esbenp.prettier-vscode", // 设置默认格式工具为prettier
"eslint.enable": true, // 开启eslint检查
"eslint.probe": ["javascript", "javascriptreact", "vue", "html"] // 打开对vue的lint,并自动fix
}
4.总结
接下来就说说所有遇到的坑吧,后面大神们可以接下面的讨论或者继续探索。
1、找了很多eslint + prettier 搭配实现代码格式化的教程也好,案例也罢。其中都用到eslint-config-prettier、eslint-config-prettier两个插件,在.eslintrc.js文件中加上"extends": ["plugin:prettier/recommended"],就可以解决eslint 和 prettier 的规则冲突,我加上了,是解决了,但是eslint却无法提升了,我的目的就是要让eslint提示,prettier格式化,所以我只能放弃加载这两个插件(希望后面的大神可以继续探索)
2、vue里面的template代码我也默认使用prettier格式化,但是出现一个问题就是格式化后html会乱换行,表现为“>”符号自动换行,找了很多方案都说设置prettier的jsxBracketSameLine(新的是bracketSameLine)禁止>单独一行,可惜都失败了,最好用了htmlWhitespaceSensitivity: 'ignore', 解决。