在团队开发中,我们总是碰到这样或者那样的问题,加分号还是不加分号?tab还是空格?换行还是不换行?你是否还在为代码风格与同事争论不休?关于代码风格,我们很难区分谁对谁错,不同的人有不同偏好,唯有强制要求才能规避争论。
所以,团队关于代码风格必须遵循两个基本原则:
- 少数服从多数;
- 用工具统一风格。
以下几个工具可以帮助你在开发中来统一我们的前端代码风格。
Eslint
Eslint大家对这种工具可能比较熟悉,它是一个可组装的JavaScript和JSX检查工具,发现并修复JavaScript代码中的问题,用来进行代码的校验。
简单的使用入门
- 安装eslint
npm install -g eslint
- 准备一个js文件来测试一下
function merge () {
var ret = {};
for (var i in arguments) {
var m = arguments[i];
for (var j in m) ret[j] = m[j];
}
return ret;
}
console.log(merge({a: 123}, {b: 456}));
- 新建一个eslint配置文件.eslintrc.js,我们以eslint:recommended为基础配置
module.exports = {
extends: 'eslint:recommended',
};
- 执行eslint merge.js
eslint merge.js
10:1 error Unexpected console statement no-console
10:1 error 'console' is not defined no-undef
✖ 2 problem (2 error, 0 warnings)
根据提示信息,我们可以知道: 第一条报错,不能使用console; 针对第 1 条提示,我们可以禁用no-console规则。将配置文件.eslintrc.js改为这样:
module.exports = {
extends: 'eslint:recommended',
rules: {
'no-console': 'off',
},
};
第二条报错,console变量未定义,不能使用未定义的变量。 这是因为 JavaScript 有很多种运行环境,比如常见的有浏览器和 Node.js,另外还有很多软件系统使用 JavaScript 作为其脚本引擎,比如 PostgreSQL 就支持使用 JavaScript 来编写存储引擎,而这些运行环境可能并不存在console这个对象。另外在浏览器环境下会有window对象,而 Node.js 下没有;在 Node.js 下会有process对象,而浏览器环境下没有。
所以在配置文件中我们还需要指定程序的目标环境:
module.exports = {
extends: 'eslint:recommended',
env: {
node: true,
},
rules: {
'no-console': 'off',
},
};
再重新执行检查时,已经没有任何提示输出了,说明merge.js已经完全通过了检查。
- 使用eslint --fix 自动修复命令
eslint提供了自动修复命令,可以对一些常见的错误进行自动修复。我们可以利用这个特性来自动格式化项目代码,这样就可以保证代码书写风格的统一。
将merge.js中的var ret = {};这一行前面多加一个空格,再执行 ESLint 检查:
eslint merge.js
2:4 error Expected indentation of 2 space characters but found 3 indent
✖ 1 problem (1 error, 0 warnings)
这时候提示的是缩进只能为 2 个空格,而文件的第 2 行却发现了 3 个空格。 之后再执行
eslint merge.js --fix
可以发现merge.js文件被修改了,新添加的空格被去除了。
以上过程通过展示了在一个简单的js文件中引入eslint,进行文件格式校验的过程,了解了eslint在项目中是如何被引入以及如何发挥作用的。
很多人刚开始接触 ESLint 时觉得太难,是因为过太过于迷信权威。刚接触eslint就直接引入一些业界已经集成好的高度定制化的配置eslint规范。比如 Airbnb 公司的 JavaScript 风格,在 GitHub 上受到了很大的好评,其实我自己也非常认可这样的编码风格。但每个团队都会根据自己的的实际情况来定制不同的东西,我们并不能随便照搬过来。 直接使用eslint-config-airbnb这种某个公司高度定制化的配置,直接用来检查整个项目好几十个JS文件,而不是eslint:recommended这样保守的。可想而知那是怎样的画面。
当我们学会了走路之后,可以试着跑一跑了,这时可以尝试引入上文提到的各大公司提供的高度配置的规范,这样当项目文件很大很多的时候可以省一些事。当然每个项目每个团队都有适合自己的开发规范,如果我们觉得 eslint-config-airbnb 规则配置中个别规则并不符合当前项目的要求,可以直接在 .eslintrc.js 配置 rules 属性,优先级高于共享规则 airbnb。
顺便说一句,如果觉得官方提供的默认规则不好用,可以自定义规则配置文件,然后发布成 Npm 包。
先学会简单地配置规则,如果要更深入地定制自己的规则,建议阅读
规则说明文档
ESLint 规则详解(一)
ESLint 规则详解(二)
文件配置
ESLint 支持几种格式的配置文件
- JavaScript - 使用 .eslintrc.js 然后输出一个配置对象。
- YAML - 使用 .eslintrc.yaml 或 .eslintrc.yml 去定义配置的结构。
- JSON - 使用 .eslintrc.json 去定义配置的结构,ESLint 的 JSON 文件允许 JavaScript 风格的注释。
- (弃用) - 使用 .eslintrc,可以使 JSON 也可以是 YAML。
- package.json - 在 package.json 里创建一个 eslintConfig属性,在那里定义配置。
如果同一个目录下有多个配置文件,ESLint 只会使用一个。优先级顺序如下
1 .eslintrc.js
2 .eslintrc.yaml
3 .eslintrc.yml
4 .eslintrc.json
5 .eslintrc
6 package.json
Prettier
Prettier翻译过来是“更漂亮的”,来看看官网对他的定义:
- 它是一款代码格式化工具,
- 支持多种语言
- 与大多数编辑器集成
- 不需要太多配置
使用prettier配置我们的项目,按下保存键,代码即被格式化,使得我们可以节省更多的时间和精力,不需要在代码评审中讨论风格。
很多人通常会将eslint与prettier混为一谈,首先从定义上看eslint是一款代码校验工具,而Prettier区别于eslint的,prettier一款代码格式化工具。 prettier不仅能格式化javascript,还能支持jsx和css。总的来说它支持以下文件格式:
- JavaScript, including ES2017
- JSX
- Angular
- Vue
- Flow
- TypeScript
- CSS, Less, and SCSS
- HTML
- JSON
- GraphQL
- Markdown, including GFM and MDX
- YAML
最重要的区别在于,prettier提供很少的配置项,它本身就是为了让用户少思考这些风格,把代码风格全部交给工具。它更像是提供了一种方案,用以保持所有输出的代码符合一致性的原则。
如何对Prettier进行配置
一共有三种方式支持对Prettier进行配置:
- 根目录创建.prettierrc文件,能够写入YML、JSON的配置格式,并且支持.yaml/.yml/.json/.js后缀;
- 根目录创建.prettier.config.js文件,并对外export一个对象;
- 在package.json中新建prettier属性。
下面我们使用prettierrc.js的方式对prettier进行配置,同时讲解下各个配置的作用。
module.exports = {
"printWidth": 80, //一行的字符数,如果超过会进行换行,默认为80
"tabWidth": 2, //一个tab代表几个空格数,默认为80
"useTabs": false, //是否使用tab进行缩进,默认为false,表示用空格进行缩减
"singleQuote": false, //字符串是否使用单引号,默认为false,使用双引号
"semi": true, //行位是否使用分号,默认为true
"trailingComma": "none", //是否使用尾逗号,有三个可选值"<none|es5|all>"
"bracketSpacing": true, //对象大括号直接是否有空格,默认为true,效果:{ foo: bar }
"parser": "babylon" //代码的解析引擎,默认为babylon,与babel相同。
}
配置大概列出了这些,还有一些其他配置可以在官方文档进行查阅。
注意一点,parser的配置项官网列出了如下可选项:
- babylon
- flow
- typescript Since v1.4.0
- postcss Since v1.4.0
- json Since v1.5.0
- graphql Since v1.5.0
- markdown Since v1.8.0 但是如果你使用了vue的单文件组件形式,记得将parser配置为vue,目前官方文档没有列出来。当然如果你自己写过AST的解析器,也可以用你自己的写的parser: require("./my-parser")。
ESLint 与 Prettier配合使用
通常,ESLint 与 Prettier配合使用。
首先肯定是需要安装prettier,并且你的项目中已经使用了ESLint,有eslintrc.js配置文件。
npm i -D prettier
配合ESLint检测代码风格
安装插件
npm i -D eslint-plugin-prettier
eslint-plugin-prettier插件会调用prettier对你的代码风格进行检查,其原理是先使用prettier对你的代码进行格式化,然后与格式化之前的代码进行对比,如果过出现了不一致,这个地方就会被prettier进行标记。
接下来,我们需要在eslint配置文件的rules中添加,"prettier/prettier": "error",表示被prettier标记的地方抛出错误信息。
//.eslintrc.js
{
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error"
}
}
借助ESLint的autofix功能,在保存代码的时候,自动将抛出error的地方进行fix。因为我们项目是在webpack中引入eslint-loader来启动eslint的,所以我们只要稍微修改webpack的配置,就能在启动webpack-dev-server的时候,每次保存代码同时自动对代码进行格式化。
const path = require('path')
module.exports = {
module: {
rules: [
{
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [path.join(__dirname, 'src')],
options: {
fix: true
}
}
]
}
EditorConfig
一些细心的童鞋可能回发现,项目里面经常会有个.editorconfig的文件,那么,它究竟是干嘛的呢?事实上,它也能帮助我们在开发中保持一定的规范。
先设想一个场景,一个大型项目,可能有很多位同事一起工作,而由于习惯的不同,导致他们用的编辑器五花八门,有vscode,有webstorm,有sublime,等等,它们默认的格式化设置是不同的,有的是2格缩进,有的则是4格。规则的不同,导致代码风格的差异,这样就会给后期的运维工作带来不可预料的风险。so bad!
所以,EditorConfig就是来做这件事的工具,它的作用就是
帮助跨不同的编辑器和ide为多个开发人员维护一致的编码风格。
知道了它是干什么,那么它是怎么用的呢?
配置EditorConfig
- 安装插件
每个编辑器都有相应的插件,这里以vscode为例,我们需要安装EditorConfig:
- 配置.editorconfig文件
在根目录下新建.editorconfig文件
# 是否是顶级配置文件,设置为true的时候才会停止搜索.editorconfig文件
root = true
[*]
# 文件编码格式,一般为utf-8
charset = utf-8
# 缩进类型
indent_style = space
# 缩进数量
indent_size = 2
# 换行符类型格式,一般用lf
end_of_line = lf
# 末尾行后加多一行空行
insert_final_newline = true
# 删除行尾的空格
trim_trailing_whitespace = true
做完以上两步后,vscode会自动的按照以上规范进行新建文件。