简单来说就是一系列配置项约束的集合:.editorconfig
➕.eslintrc
➕.prettierrc
➕git hooks
。
EditorConfig
我们知道不同的开发人员对 IDE 的使用偏好都有差别,但是一些缩进类的配置都是共通的,一套代码我们肯定不希望在开发 A 那里是 2 个空格的 tab,跑到开发 B 那边就变成了 4 个空格的 tab。一方面你配置的prettier
或者eslint
可能会 ⚠️,另一方面 git 检测也会认为是 diff。
所以有了 EditorConfig,它通过在项目中直接配置.editorconfig
,可以保证缩进方式、缩进长度、换行、编码等的一致性。
根据EditorConfig 官方的说法,大部分 IDE 本身就支持对.editorconfig
配置文件的支持。我们仅需创建并编辑我们的规则即可。
EditorConfig 会自上而下寻找对应的.editorconfig
配置,所以理论上你可以配置多个,并且离当前目录树最近的一级配置文件具有最高的优先级。
当然我们一般都是在主入口层级配置一个统一的。另外这个文件要么放在项目根目录要么在配置文件中编写root=true
。
至于配置方式在官网上有 Example 说明,不过作为 FE dev,看下业内的库可能更直观,就拿jquery
的配置来说:
1 | # This file is for unifying the coding style for different editors and IDEs |
indent_style
用来设置缩进的类别,有tab
和space
两种选择。indent_size
是当我们选择indent_style = space
时,才配置该属性,描述的是单位缩进的列数。tab_width
是当我们选择indent_style = tab
时对应的单位缩进的列数。end_of_line
为换行时选择的换行符,有lf
、cr
,crlf
三种选择。一般开源的库都选择lf
,linux、os x,max os 使用lf
,win 使用crlf
。(逼乎上有讨论说cr
在 linux 类系统下问题很大,但是 win 中不用cr
不会有很大问题,emm🤷♂️trim_trailing_whitespace
置为true
,会将每行后面多余的空格移除,false
则会保留。insert_final_newline
置为true
,会在保存文件后在文件末尾新增一个空白行,false
则不会。charset
,字符编码,通常使用utf-8
。
以上是配置,本人使用的 IDE 是 VS Code,我要怎么使这些配置生效呢?
Extensions
安装插件EditorConfig for VS Code
插件。- 在当前文件选取内容,快捷格式化操作 mac:
⌥ + ⇧ + F
, win:alt + shift + F
。
ESLint
之前也写过一篇关于 ESLint 配置的文章,见《关于 ESLint》。
ESLint 提供了一套潜在问题和写法的纠错机制,它根据一些定制逻辑会提供开发者对应的错误和警告。
我们一般可以通过 CI 生成一份初始化 ESLint 文件:
npm i -g eslint
,安装全局 CI,可能要使用root
权限。eslint --init
根据命令行提示,选择我们需要的初始化配置。
比如我根据我在浏览器环境生成了一份json
格式的初始配置文件,配置如下:
1 | { |
可以看到env
就是我们所处的 js 宿主环境;extends
则会去继承相关eslint
的配置规则,数组格式后面的配置项内的重复类型规则会覆盖之前的;parserOptions
主要告诉编译器将源代码转成什么内容格式的AST
进行规则分析和处理;plugins
可以理解为自定义的 ESLint 检测,通常是一些比较细节的定制化扫描,其中的插件会挂载到校验环境中,并在rules
中提供细节开关指定使用;rules
中还支持我们额外的单条检测的定制处理。
Unexpected lexical declaration in case block(no-case-declarations)
在个人项目执行规范时,有个小插曲,即报了Unexpected lexical declaration in case block
的error
类校验提示。
定位后发现是在switch...case...
语句中,分支条件代码块中进行了变量声明,但未使用{}
包裹该代码块。
这样操作会有潜在风险,因为在整个switch...case...
中,我们的变量都声明在同一个上下文内,所以如果不用{}
包裹,对一个变量名的声明会导致重复声明抛错:Uncaught SyntaxError: Identifier xxx has already been declared
,也就意味着不同条件分支都可能会重新对其进行赋值,产生副作用。
举些 🌰:
1 | switch (1) { |
一些依赖的插件
如果使用了css-modules
,并希望得到一些是否引用其中样式的检测,需要安装插件eslint-plugin-css-modules
。
Prettier
前面我们进行了 EditorConfig 和 ESLint 的讨论,它们的职能分别对应IDE 编辑风格规范和代码问题及风格的检测规范。
而Prettier
,它不具备任何代码规范的纠错能力,它只是一个风格上的统一工具,这里的风格指的是类似每行代码结尾是否需要;
、字符串使用单引号还是双引号包裹,最后的变量引入或者声明是否补,
等问题。
我们可以直接在项目下创建.prettierrc
文件进行配置,配置文档见Options:
1 | { |
package.json
下也要在devDependencies
依赖下安装对应 Prettier 依赖:
1 | npm i -D prettier eslint-plugin-prettier eslint-config-prettier |
安装后,还要在之前的.eslintrc.json
下的plugins
数组中添加prettier
,注意prettier
要放在插件的最后一个。
然后我们还要像前文中描述的,在rules
下手动激活prettier
插件中的配置项,error
表示该插件规则命中时会在控制台报错:
1 | { |
P.S.此处的写法可以省略并简化成extends
中的一句:
1 | { |
最后同样要在Extensions
中安装Prettier - Code formatter
插件。
Git Hooks
原理是利用git的hooks能力,在提交前应用我们的校验规则。
比较主流的做法是使用husky
➕lint-staged
,前者会将其配置集成到git hooks下的pre-commit
阶段并在提交前校验。后者则是限制应用范围。
对于一个大型项目而言,代码量是非常巨大的,如果我们贸然使用前文中的prettier
之类的进行格式化,会造成大量的文件变更,这样的commit
会引起很多不必要的麻烦(如修改了历史提交人信息、造成code review人员额外的工作负担等),所以通过lint-staged
会使规则只在我们最新的提交内容内生效,因此缩小了影响范围。
要应用肯定得先进行安装:
1 | npm i -D husky lint-staged |
在package.json
中配置:
1 | "husky": { |
此时当我们进行git commit -m "xxx"
代码提交时,就会按照以下顺序处理代码内容:
- 检视所有更改的代码内容,此处只进行
js
后缀格式内容扫描。 - 先使用
eslint
进行修复。 - 使用
prettier
进行代码风格统一。 - 将变动内容重新应用进缓冲区。
Web Hooks
实际上前文中讨论的校验规则都是在开发者本地配置的,有很多方式可以绕开(--no-verify
、剔除git hooks等)。
如果有强要求规范,可以将这些规则上到服务端。通过配置web hooks,可以在服务端拒绝我们的不符合规范的提交内容。