前端代码规范最佳实践:eslint+prettier+editorconfig+lint-staged

【前言】

项目开发过程中,用到各种代码规范性工具。

时不时就会出现,多种工具重复作用,相互之间有冲突的情况。

比如:按照 prettier 的规则格式化的代码,不符合 eslint 的规定。于是 eslint 报错。


本文,旨在彻底理清各代码规范工具的作用,并提供无冲突配合使用的解决方案。

文章整理自:https://blog.theodo.com/2019/08/empower-your-dev-environment-with-eslint-prettier-and-editorconfig-with-no-conflicts/

其中附带了一些自己的理解。如有偏差,烦请指正。


一、开始做事之前,先明确目的

问自己一个问题:

为项目配置代码规范,要达到什么目的?


【答案】

1.开发过程中,如果写出不符合我们规范的代码,能够及时提醒开发者,便于及时修复(eslint的能力)

2.保存/粘贴代码时、使用格式化快捷键时,能够自动按照我们制定的规范、格式化代码(prettier的能力)

3.不同开发者如果使用不同的编辑器(sublime/vscode)或系统(windows/mac),能够执行统一的代码风格标准。比如:缩进是tab还是space,结尾end_of_line是lf还是crlf(editorconfig的能力 —— 用于覆盖编辑器的默认配置)


二、再次明确 eslint、prettier、editorconfig 各自能力

1.eslint

通过配置 .eslintrc.* 制定团队代码规范。

在代码编写的过程中,出现不符合规范的代码,进行红线提示。帮助开发者及时更正不符合规范的代码。

同时,提供命令行检查规范及 auto-fix 能力。

【具体】

检查 main.js 文件的代码规范:

npx eslint main.js

自动修复 main.js 部分规范问题(通常如:缺少/多余分号,缩进格式等):

npx eslint main.js --fix

【注意】

eslint 的 auto-fix,能够修复的规范问题比较有限。

通常,需要较大变动才能修复的规范问题,eslint 无法自动修复。如:单行不能超过 80 个字符。

2.prettier

根据规范,自动格式化代码。具有比 eslint auto-fix 更加强大的代码规范性修复能力。

npx prettier main.js --write

prettier 会根据 .eslintrc.* 的约定,修复 main.js 的规范性问题。包括较大变动才能修复的规范问题。如:单行不能超过 80 个字符。

3.editorconfig

编辑器配置。用于覆盖编辑器默认配置,以确保不同编辑器之间,代码格式的统一。

比如,使用 editorconfig,规定开发过程中,点击 tab 按钮,是以 tab 格式进行缩进,还是以 space 格式进行缩进。

如果没有约定,不同的编辑器,或者相同编辑器、不同开发者的配置存在差异,可能出现,有的人是 tab 缩进、有的人是 space 缩进的情况,造成代码风格的差异。

【注】

vscode 这类编辑器,需要自行安装 editorconfig 插件。


三、进行配置(js文件)

1.安装 eslint + prettier

yarn add eslint prettier -D

2.安装 eslint-config-prettier

yarn add eslint-config-prettier -D

【作用】

让所有可能会与 prettier 规则存在冲突的 eslint rule,失效,并使用 prettier 的规则进行代码检查。

相当于,用 prettier 的规则,覆盖掉 eslint:recommended 的部分规则。

后面 prettier 格式化,也会根据这个规则来。因此,不会再有冲突。

【使用】

.eslintrc.js

{

    "extends": ["eslint:recommended", "prettier"]

}


3.安装 eslint-plugin-prettier

yarn add eslint-plugin-prettier -D

【作用】

将 prettier 的能力集成到 eslint 中。按照 prettier 的规则检查代码规范性,并进行修复。

【使用】

.eslintrc.js

{

    "rules":{

        "prettier/prettier":"error" // 不符合 prettier 规则的代码,要进行错误提示(红线)

    },

    "plugins": ["prettier"]

}

{

    "extends": ["eslint:recommended","plugin:prettier/recommended"]

}

【看一下效果】

npx eslint --fix main.js

至此,eslint 会拥有和 prettier 一样的修复能力。

像 prettier 一样,格式化所有不符合规范的代码。


4.使用编辑器,自动格式化代码

(1)使用自己编辑器的快捷键,格式化代码

以 vscode 为例:shift + option + f

默认格式化规则选择 prettier,即可完成代码格式化。

(2)保存代码,自动格式化

同样以 vscode 为例,打开你的 settings.json,添加下面这句话:

"editor.formatOnSave": true

【注】

至此,js、json、less等文件,均可实现自动格式化。

文件格式化规则,遵从我们在 .eslintrc.js 里的配置。也就是,使用我们的 prettier 插件默认规则去格式化。

【附】

如果你使用的是 webstorm,或许可以参考这个 https://www.jianshu.com/p/2f3cad152192


5.规则定制化

保存任意 js 文件,观察当前规则是否符合期望。如果不符合,根目录下创建 .prettierrc,进行定制化配置。

如 .prettierrc 如下:

{

      "singleQuote": true

}

再次保存代码,prettier 将会把 js 文件中的双引号,全部格式化为单引号。


至此,对 js 文件的规范定义与自动格式化配置,全部完成。

【注】

这里的 .prettierrc,具有格式化规则的最高优先级。


四、让 eslint 认识 js 以外的更多语法【以 typescript 为例】

1.安装

(1)使用 ts,自然要安装 typescript

(2)为了让 eslint 认识 ts 语法,要安装相应的 parser

(3)为了指定 ts 代码的规范,要安装相应的 plugin

yarn add typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin -D


2.配置

{

    "parser":"@typescript-eslint/parser",

    "extends":["plugin:@typescript-eslint/recommended", "eslint:recommended", "prettier"],

    "env":{

        "es6":true,

        "node":true

    },

    "rules":{

        "prettier/prettier":"error"

    },

    "plugins": ["prettier"]

}

【注】extends 的含义

告诉 eslint,根据指定的规范,去检查指定类型的文件。

如上例:

根据 @typescript-eslint/recommended 规范,检查 ts 代码。

根据 eslint:recommended + prettier 规范,去检查 js 代码。

当某一类型的文件,被制定了不止1个规范,存在某些规范冲突时,后面的会覆盖掉前面的。

在本例中,prettier 制定的规范,会覆盖掉 eslint:recommended 的某些规范。

eslint 会按照覆盖后的规则,去检查 js 文件。


3.使用

npx eslint --fix main.ts

【如果能够正常格式化】

done。

【如果出现问题】

这里,eslint 会使用 prettier 插件,根据 prettier 的规则格式化代码。

但同时,eslint 会根据 @typescript-eslint/recommended 的规则,检查代码规范性。

当 @typescript-eslint/recommended 的规则和 prettier 的规则出现不一致,就会造成,格式化后的代码,报 eslint 错误的问题。


4.解决冲突(如果存在冲突)

使用相应的 prettier 插件,消除冲突。

也就是说,prettier 的规则和 @typescript-eslint/recommended 存在冲突,那就使用 prettier/@typescript-eslint 插件。

和前面,使用 eslint-config-prettier 消除 eslint:recommended 与 prettier 的规则冲突,同理。

具体可以使用那些插件,查阅:https://github.com/prettier/eslint-config-prettier

它们全部由 eslint-config-prettier 这个库提供。

{

   "parser":"@typescript-eslint/parser",

    "extends":[

        "plugin:@typescript-eslint/recommended", 

        "eslint:recommended", 

        "prettier", 

        "prettier/@typescript-eslint"

    ],

    "env":{

        "es6":true,

        "node":true

    },

    "rules":{

        "prettier/prettier":"error"

    },

    "plugins": ["prettier"]

}

【注意】

这里,不要通过手动写 rules,去消除出现的冲突。

因为,已经发现的冲突,可能只是部分冲突,手写 rule 不能完整解决冲突问题,会存在遗漏。


5.自定义规则

当 prettier 插件的默认规则,与团队习惯不符合时,进行规则自定义。

(1)校验规则定义(.eslintrc.js)

{

   "parser":"@typescript-eslint/parser",

    "extends":[

        "plugin:@typescript-eslint/recommended", 

        "eslint:recommended", 

        "prettier", 

        "prettier/@typescript-eslint"

    ],

    "env":{

        "es6":true,

        "node":true

    },

    "rules":{

        "prettier/prettier":"error",

        // 比如,自定义缩进约束为4格(注意:这个规则会对所有文件生效,不只是ts)      

        "@typescript-eslint/indent": ["error", 4]     

    },

    "plugins": ["prettier"]

}

(2)格式化规则定义(.prettierrc)

{

    "tabWidth": 4  // 与 eslint 的自定义规则保持一致

}


五、Prettier 和 EditorConfig

有些规则,editorconfig 和 .prettierrc 同时可以定义。

因此,我们要避免冗余、重复的定义。

这些规则如下:

end_of_line

indent_style

indent_size/tab_width

max_line_length

我们将这些规则的定义,均放在 .editorconfig 中。

配置好 .editorconfig 后,保存代码,即使没有配置 .prettierrc,prettier 也会按照 .editorconfig 的定义来格式化代码。


六、规范检查增强(husky + lint-staged)

在 git commit 之前,先强制执行prettier格式化(防止某些成员开发期间不开启编辑器格式化)、再检查代码规范,如果检查不通过、阻止提交。

1.新建 .eslintignore + .prettierignore

.eslintignore、.prettierignore,参考如下:

.DS_Store

node_modules

dist


.gitignore

.eslintignore

.prettierignore

LICENSE

README.md

yarn.lock

# local env files

.env.local

.env.*.local

# Log files

npm-debug.log*

yarn-debug.log*

yarn-error.log*

# Editor directories and files

.idea

.vscode

*.suo

*.ntvs*

*.njsproj

*.sln

*.sw?


2.安装

yarn add husky lint-staged -D


3.使用

package.json添加:

"scripts": {

    "lint": "eslint .",

    "prettier": "prettier --write ."

},

"husky": {

    "hooks": {

      "pre-commit": "lint-staged"

    }

  },

  "lint-staged": {

    "*": [

        "npm run prettier", 

        "npm run lint",

        "git add ."

    ]

  }

git commit 之前,会自动使用 prettier 格式化 ignore 之外的代码。格式化后,自动检查所有文件,是否全部符合 eslint 规范。

存在不符合规范的代码,git commit 将被终止。

【注】

因为 prettier 只是会帮我们格式化代码,并不能够修复所有 eslint 错误,比如定义未使用的变量,prettier 不会自动帮我们删除,要手动删除。

因此,prettier 后再 eslint,是有必要的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335