工欲善其事,必先利其器
比喻要做好一件事,准备工具非常重要。找到了好的工具能做的事半功倍的作用;而且做起来也很舒服啊。
前言
有时候我想看别人提交的代码改了什么东西,结果他们改了个小东西,保存的时候把整个文件按照他本地规则格式化了…我¥%&#@
需求
所以我想要一套好的代码规范,代码格式化,并且能满足不同的项目差异化,还能覆盖用户的本地规范。
点了一份vsCode
插件EditorConfig
eslint
Prettier
套餐。
一个项目下会包括这几个文件,这就是套餐内配的几个文件了。
EditorConfig
EditorConfig 帮助使用不同IDE开发同一个项目的开发者,维持固定统一的代码风格。简而言之,EditorConfig就是为了抹平不同IDE的代码格式差异的
通常在项目根目录下,添加.editorconfig
配置文件,贴一份常见的配置
# http://editorconfig.org
root = true
# 说明
## 设置文件编码为 UTF-8;
## 用两个空格代替制表符;
## 在保存时删除尾部的空白字符;
## 在文件结尾添加一个空白行;
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
复制代码
eslint
eslint
的关注点是代码质量和代码格式。
何为代码质量?如未使用变量、三等号、全局变量声明等问题
何为代码格式?如单行代码太长、tab的长度、空格、逗号,单双引号等问题
对于质量和格式问题,eslint可以给出错误或警告提示,也可以自动修复,autofix;
使用
安装依赖之后,可以在项目根目录下创建.eslintrc.js
文件:定义代码规则。
创建.eslintignore
文件:定义过滤检查的文件。
会在文章最后贴上一份.eslintrc.js
配置,具体规则可根据自身需要修改。
需要自动修复代码的话,需要配置vscode
的settings.json
文件
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
}
}
复制代码
也可以在项目下创建vscode规则,项目根目录创建
.vscode
目录,目录下创建settings.json
文件,添加上面代码,就会替换开发者本地的配置。
Prettier
Prettier
:代码的格式化和修复。
代码检测的话eslint更优秀,eslint也支持了代码修复。但是Prettier更擅长做代码格式修复的问题。比如有些eslint不支持自动修复,但是Prettier就能实现。
使用
直接在eslint内引入
module.exports = {
extends: ['prettier/prettier'],
}
复制代码
或者在vscode配置下配置规则
// 默认使用prettier格式化支持的文件
"vetur.format.defaultFormatter.js": "prettier",
"vetur.format.defaultFormatter.html": "prettyhtml",
"vetur.format.defaultFormatterOptions": {
"prettier": {
// "wrap_attributes": "force-aligned", //也可以设置为“auto”,效果会不一样
// 结尾有分号
"semi": 1,
// 超过140个字符换行
"printWidth": 100,
// 使用单引号
"singleQuote": true,
// 无尾随逗号
"trailingComma": "none",
// 箭头函数单个参数不加分号
"arrowParens": "avoid"
},
"prettyhtml": {
"printWidth": 100
}
},
复制代码
最后贴上eslint代码
// "off" or 0 - turn the rule off
// "warn" or 1 - turn the rule on as a warning (doesn't affect exit code)
// "error" or 2 - turn the rule on as an error (exit code will be 1)
module.exports = {
root: true,
env: {
node: true,
es6: true,
},
extends: ['plugin:vue/essential', 'prettier/prettier'],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', //生产环境 禁止 console
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', // 生产环境 禁止 debugger
// "prettier/prettier": "off",
/*
---------------
POSSIBLE ERRORS
---------------
*/
'no-extra-semi': 1, // 禁止多余的分号
'for-direction': 2, // for 循环死了
'no-cond-assign': 2, // 防止 if 写成赋值
'no-dupe-args': 2, // 禁止参数重名
'no-dupe-keys': 2, // 禁止 key 重名
'no-duplicate-case': 2, // 禁止 case 重复
'no-func-assign': 2, // 禁止覆盖函数字面量
'no-inner-declarations': [2, 'both'], // 禁止在 if 中 var
'no-irregular-whitespace': 2, // 禁止非常规空白
'no-prototype-builtins': 2, // 禁止直接调用 obj 上的 proto 方法
'no-sparse-arrays': 2, // 防止数组中多余的逗号
'no-template-curly-in-string': 2, // 禁止字符串中出现 ${}
'no-unreachable': 2, // 禁止出现无法执行到的语句
'no-unsafe-finally': 2, // 禁止 finally 出现控制语句
'no-unsafe-negation': 2, // 禁止有歧义、不安全的 ! 号
'use-isnan': 2, // 强制 isNaN()
'valid-typeof': 2, // 防止 typeof 类型的字符写错
// "valid-jsdoc": 2, // 如果有的话,校验 jsdoc
/*
--------------
BEST PRACTICES
--------------
*/
// "curly": 2, // 控制语句块强制大括号(冲突 nonblock-statement-body-position)
// "no-case-declarations": 2, // 强制 case 加大括号,明确 let 等的作用域(非 es6 无意义)
'accessor-pairs': 2, // 如果 setter,则不能没有 getter
'block-scoped-var': 2, // 禁止块级作用域中 var 和使用该 var
'default-case': 2, // switch 强制 default
'no-alert': 2, // 禁止 alert prompt confirm 等
'no-caller': 2, // 禁止 arguments.caller
'no-eval': 2, // 禁止 eval
'no-extra-bind': 2, // 禁止无意义的 bind() 调用
'no-fallthrough': 2, // 禁止 case fallthrough
'no-floating-decimal': 2, // 禁止省略形式的浮点定义
'no-global-assign': 2, // 禁止覆盖全局对象
'no-implied-eval': 2, // 禁止隐式的 eval,比如 setTimeout
'no-iterator': 2, // 禁止替换原生的 __iterator__
'no-proto': 2, // 禁止使用 __proto__
'no-labels': 2, // 禁止使用 label 语句
'no-lone-blocks': 2, // 禁止无意义的 block 标记
'no-new-func': 2, // 禁止使用 Function
'no-new-wrappers': 2, // 禁止使用带 new 的基本类型封装
'no-redeclare': 2, // 禁止重复声明
'no-return-assign': 2, // 禁止不打括号的 return 赋值
'no-sequences': 2, // 禁止使用逗号运算符
'no-throw-literal': 2, // 禁止 throw 文本
'no-useless-concat': 2, // 禁止无意义的拼接
'no-useless-escape': 2, // 禁止无意义的转义
'no-void': 2, // 禁止使用 void
'no-with': 2, // 禁止使用 with
yoda: [2, 'never'], // 禁止反向的判断比较
'no-return-await': 2, // 禁止没有意义的 return 时使用 await
'require-await': 2, // 禁止 async 的 func 中没有 await
'dot-notation': [1, { allowKeywords: false }], // 警告:不必要的计算属性访问 or 直接访问关键字为 key 的属性
'no-eq-null': 1, // null 必须 ===
'vars-on-top': 1, // 建议变量都定义在 scope 顶部
// radix: 1, // 建议 parseInt 带上进制参数
// "no-invalid-this": 1, // 限制 this 的使用
// "consistent-return": 1, // 建议统一 return
// "no-else-return": 1, // 建议统一 return
'no-useless-return': 1, // 建议删除、合并没有意义的 return
// "guard-for-in": 1, // for in 的警告(观察观察)
// 如果 method 没有使用 this,应该使用 static
// "class-methods-use-this": [1, { "exceptMethods":["render"] }],
// 强制 promise reject error 对象
// "prefer-promise-reject-errors": [2, { allowEmptyReject: true }],
// 强制 IIFE 必须打括号
'wrap-iife': [2, 'any', { functionPrototypeMethods: true }],
// 禁止魔法数字
// "no-magic-numbers": [1, { "detectObjects":true, "ignoreArrayIndexes":true, "ignore":[0,1,-1] }],
/*
----------------
STYLISTIC ISSUES
----------------
*/
'comma-spacing': 1, // 警告:逗号无空格间隔
'computed-property-spacing': 1, // 警告:计算属性左右加空格
'consistent-this': 0, // 警告:不规范的 this 别名
'eol-last': 1, // 警告:文件末无空行
'func-call-spacing': 1, // 警告:不规范的调用前空格
'new-parens': 1, // 警告:new 调用必须打括号
// "no-lonely-if": 1, // 警告:else 中的只有 if 不合理
// "no-mixed-operators": 1, // 警告:表达式中运算符过于复杂
'no-mixed-spaces-and-tabs': 1, // 警告:混合了 tab 和 space
'no-unneeded-ternary': 1, // 警告:精简条件表达式
'object-curly-spacing': [1, 'always'], // 警告:obj 大括号需要空格
semi: 1, // 警告:缺少分号
'semi-spacing': 1, // 警告:分号后需要空格
'switch-colon-spacing': 1, // 警告:case 冒号需要空格
'spaced-comment': 1, // 警告:注释需要空格
'space-unary-ops': 1, // 警告:一元符空格问题
'space-infix-ops': 1, // 警告:运算符必须空格
'key-spacing': [1, { mode: 'minimum' }], // 警告:obj 的 key 冒号需要空格
'jsx-quotes': 1, // 警告:jsx 最好用双引
'no-whitespace-before-property': 2, // 禁止 dot 属性访问带空格
'nonblock-statement-body-position': 2, // 强制单句控制写成一行
// 警告:链式调用必须断行,3 级以上
'newline-per-chained-call': [1, { ignoreChainWithDepth: 3 }],
// 函数小括号的空格定义
'space-before-function-paren': [
1,
{
anonymous: 'never',
named: 'never',
asyncArrow: 'always',
},
],
// 引号规则
quotes: [1, 'double', { allowTemplateLiterals: true }],
// 强制属性引号
'quote-props': [2, 'as-needed', { keywords: true }],
// 警告:行末空格
'no-trailing-spaces': [1, { skipBlankLines: true }],
// 警告:缩进 tab
indent: ['error', 'tab'],
// 小括号中的空格
'space-in-parens': [1, 'never'],
},
parserOptions: {
parser: 'babel-eslint',
},
}
复制代码