-
Notifications
You must be signed in to change notification settings - Fork 0
Description
关于规范
是否在犹豫到底句尾加不加分号?
是否有过和同事争执哪种写法更优雅更易维护的经历?
是否争执过后痛不欲生的发现人和人之间无法互相理解?
参考下 standard
的哲学吧!
Just use
standard
and move on. There are actual real problems that you could spend your time solving! :P
确定一个开箱即用的规范然后就严格执行吧!(如果你有拍板能力的话...
Eslint基本配置和vscode插件配置
尽管在代码格式化上面有许多好用的命令行工具: prettier
、 standard
、 tslint
...
但是考虑到不同技术栈对格式化要求不同、想要同时使用某几种风格、灵活性等情况,个人还是更加倾向基于 eslint
通过扩展和插件来配置项目代码规范的方式。目前各类热门的格式化工具或风格也都有 eslint
的扩展或者插件。
同时,基于 eslint
来扩展这种方式,无需为不同业务场景或项目安装额外的IDE插件或命令行工具
Eslint 基本配置
关于各种类型的 Eslint
配置文件如果同时出现,优先级如下:(通常不会这么做)
.eslintrc.js
.eslintrc.yaml
.eslintrc.yml
.eslintrc.json
.eslintrc
package.json
以 .eslintrc.json
为例,常见的核心配置项如下:
.eslintrc.json
{
// 解析器
"parser": "esprima",
// 定义一组预定义的全局变量
"env": { "es6": true },
// 解析器选项(不同的解析器选项可能会不同)
"parserOptions": {
// ECMAScript版本(只启用语法,不启用新全局变量,如Set)
"ecmaVersion": 5,
// 额外的语言特性
"ecmaFeatures": {},
// ECMAScript模块
"sourceType": "module"
},
// 可共享的配置包
"extends": [],
// 插件提供额外的校验规则
"plugins": [],
// 具体的规则
"rules": {
// ...
}
}
关于 extends
和 plugins
:
传入 plugins
选项的插件包会提供额外的规则实现,原理是在 eslint
将代码解析为AST后将上下文传入规则对应的回调函数,回调函数会进行一系列的校验操作。
传入 extends
选项的扩展包本身并不提供额外的规则实现,仅仅是提供一个预设的 .eslintrc.json
与本地的 .eslintrc.json
进行增量合并(本地的配置项优先级高于扩展包) 。如果传入多个扩展包的数组,相同的配置项后者会覆盖前者。
扩展包
eslint-config-standard
源码
{
"parserOptions": {
"ecmaVersion": 2021,
"ecmaFeatures": {
"jsx": true
},
"sourceType": "module"
},
"env": {
"es2021": true,
"node": true
},
"plugins": [
"import",
"node",
"promise"
],
"globals": {
"document": "readonly",
"navigator": "readonly",
"window": "readonly"
},
"rules": {
"no-var": "warn",
// ...
}
}
因此本地安装依赖后,只需要在配置文件中声明扩展,无需任何额外配置项。需要注意的是,扩展包一般会将依赖声明为 peerDependencies
,npm
不同版本对于 peerDependencies
处理方式不太一样。
本地 .eslintrc.json
{
"extends": ["standard"] // eslint-config- 可省略
}
Vscode的插件配置
- 首先需要安装插件
ESLint
- 打开
setting.json
,添加如下配置
{
"vetur.format.enable": false, // 关闭其他插件的format
"editor.tabSize": 2,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true // 保存的时候fix可以格式化的eslint问题
},
"editor.formatOnSave": true, // 开启保存格式化
"eslint.format.enable": true, // 将eslint作为formatter
"eslint.validate": [ // 哪些语言需要被eslint校验
"javascript",
"javascriptreact"
],
}
记录一下目前用到的一些风格方案
1. React + React Hooks + Standard
standard + standard-jsx
npm install --save-dev eslint-config-standard eslint-config-standard-jsx eslint-plugin-promise eslint-plugin-import eslint-plugin-node eslint-plugin-react
react-hooks
npm install --save-dev eslint-plugin-react-hooks
jsx-a11y
npm install --save-dev eslint-plugin-jsx-a11y
.eslintrc.json
{
"extends": [
"standard",
"standard-jsx"
],
"plugins": [
"react-hooks",
"jsx-a11y"
],
"rules": {
"no-console": "warn",
"comma-dangle": [
"error",
"always-multiline"
]
}
}
2. React + React Hooks + TS + Standard
standard-with-typescript
npm install --save-dev eslint@7 eslint-plugin-promise@4 eslint-plugin-import@2 eslint-plugin-node@11 @typescript-eslint/eslint-plugin@4 eslint-config-standard-with-typescript
react + react-hooks + jsx-a11y
npm install --save-dev eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y
tsconfig.json
{
"compilerOptions": {
"target": "es6",
"strict": true,
"module": "esnext",
"moduleResolution": "node",
"experimentalDecorators": true,
"jsx": "react",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"lib": [
"es2015",
"es2016",
"es2017",
"dom"
],
"resolveJsonModule": true
},
"includes": [
"./declare/externals.d.ts"
],
"exclude": [
"node_modules"
]
}
.eslintrc.json
{
"extends": [
"standard-with-typescript"
],
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": [
"react",
"react-hooks",
"jsx-a11y"
],
"rules": {
"no-console": "warn",
"comma-dangle": [
"error",
"always-multiline"
]
}
}
3. Vue + Airbnb
babel-eslint + eslint-plugin-vue
npm install --save-dev eslint-plugin-vue babel-eslint
airbnb-base
npx install-peerdeps --dev eslint-config-airbnb-base
.eslintrc.js
module.exports = {
root: true,
env: {
node: true,
},
extends: ['plugin:vue/recommended', 'airbnb-base'],
parserOptions: {
parser: 'babel-eslint',
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'import/no-unresolved': 'off',
'vue/max-attributes-per-line': ['error', {
singleline: 3,
multiline: {
max: 1,
allowFirstLine: false,
},
}],
},
};