ESLint+Prettier代码规范实践

前提

本文并不单独讲解 ESLint 和 Prettier 如何配置和运行。

问题

想在团队中推行一定的代码规范,并给不符合规范的代码做检测和提示。

方案

代码规范校验使用 ESLint,但是一开始 ESLint 只有检测告诉你哪里有问题,常常出现的情况就是一堆 warning,改起来很痛苦。后来 ESLint 提供了 $ ESLint filename --fix 的命令可以自动帮你修复一些不符合规范的代码。Prettier 是一个代码格式化工具,可以帮你把代码格式化成可读性更好的格式,最典型的就是一行代码过长的问题。

Lint和Prettier区别

那 ESLint 和 Prettier 的区别是什么呢?eslint(包括其他一些 lint 工具)的主要功能包含代码格式的校验,代码质量的校验。而 Prettier 只是代码格式的校验(并格式化代码),不会对代码质量进行校验。代码格式问题通常指的是:单行代码长度、tab长度、空格、逗号表达式等问题。而代码质量问题指的是:未使用变量、三等号、全局变量声明等问题。

Lint和Prettier配合使用

为什么要两者配合使用?因为,第一在 ESLint 推出 --fix 参数前,ESLint 并没有自动化格式代码的功能,要对一些格式问题做批量格式化只能用 Prettier 这样的工具。第二 ESLint 的规则并不能完全包含 Prettier 的规则,两者不是简单的谁替代谁的问题。但是在 ESLint 推出 --fix 命令行参数之后,如果你觉得 ESLint 提供的格式化代码够用了,也可以不使用 Prettier。

ESLint 和 Prettier 相互合作的时候有一些问题,对于他们交集的部分规则,ESLint 和 Prettier 格式化后的代码格式不一致。导致的问题是:当你用 Prettier 格式化代码后再用 ESLint 去检测,会出现一些因为格式化导致的 warning。这个时候有两个解决方案:

  1. 运行 Prettier 之后,再使用 eslint --fix 格式化一把,这样把冲突的部分以 ESLint 的格式为标准覆盖掉,剩下的 warning 就都是代码质量问题了。
  2. 在配置 ESLint 的校验规则时候把和 Prettier 冲突的规则 disable 掉,然后再使用 Prettier 的规则作为校验规则。那么使用 Prettier 格式化后,使用 ESLint 校验就不会出现对前者的 warning。

为什么不能先使用 ESLint 再使用 Prettier。针对方案1,如果你后使用 Prettier,那么格式化后提交的代码在下一次或者别人 checkout 代码后是通不过 lint 校验的。针对方案2,其实是可以的,但是本人在实践中看社区方案的时候有提到某些情况下 eslint --fix 和 prettier 混用会出现格式问题。所以保险起见还是先用 perttier 格式化,再用 eslint 命令校验,而不用 eslint --fix 命令去格式化。

方案一实践

  1. 安装 prettier-eslint(Tip:所有方案前提是你已经安装 eslint 和 prettier 相关包):

    $ npm install --save-dev prettier-eslint prettier-eslint-cli
    
  2. 运行

    $ npm prettier-eslint "src/**/*.js"
    

    prettier-eslint 会一次执行 prettier 和 eslint --fix 命令。整个流程是:Code ➡️ prettier ➡️ eslint --fix ➡️ Formatted Code。prettier-eslint 的各种参数请参看 https://github.com/prettier/prettier-eslint-cli

方案二实践

方案二的思路主要是在 eslint 的规则配置文件上做文章,安装特定的 plugin,把其配置到规则的尾部,实现 prettier 规则对 eslint 规则的覆盖。

  1. 安装 plugin:

    $ npm install --save-dev eslint-config-prettier
    
  2. 在 .eslintrc.* 文件里面的 extends 字段添加:

    {
      "extends": [
        ...,
        "已经配置的规则",
    +   "prettier",
    +   "prettier/@typescript-eslint"
      ]
    }
    
    

    我使用的是 TypeScript,所以 plugin 的名字是 prettier/@typescript-eslint。

    如果你想 disable 掉更多的规则可以是如下:

    {
      "extends": [
        ...,
        "已经配置的规则",
        "prettier",
        "prettier/@typescript-eslint",
        "prettier/babel",
        "prettier/flowtype",
        "prettier/react",
        "prettier/standard",
        "prettier/unicorn",
        "prettier/vue"
      ]
    }
    
    

    看名字应该能猜到每个对应的是 disable 哪些规则了吧。

  3. 完成上述两步可以实现的是运行 eslint 命令会按照 prettier 的规则做相关校验,但是还是需要分别运行 prettier 和 eslint 命令。社区有一个方案整合了上述两步,在使用 eslint --fix 时候,实际使用 prettier 来替代 eslint 的格式化功能。
    安装:

    $ npm install --save-dev eslint-plugin-prettier
    

    修改 .eslintrc.*

    {
      "extends": [
        ...,
        "已经配置的规则",
        "plugin:prettier/recommended"
      ]
    }
    
    

    这个时候你运行 eslint --fix 实际使用的是 Prettier 去格式化文件。eslint-plugin-prettier 具体详细的配置见:https://github.com/prettier/eslint-plugin-prettier

和VSCode集成使用

上面所有讲到的内容都是在你写完代码去校验的,使用的是命令行工具。如果你是一个新手,对规范不是很熟悉,那么碰到的问题就是写完代码运行命令行工具后产生海量的 warning。这个时候改起来真的很打击积极性。如果能够在写的代码的时候让编辑器提示就能及时改正了。自然我们社区也提供了很多方案,各家的编辑器 Atom、Sublime、VSCode 等主流的编辑器都有相关的插件。我就以 VSCode 为例:

  1. 下载 ESLint Extension


    vscode-eslint-extension.png
  2. 配置 .eslintrc.*

module.exports =  {
  parser:  '@typescript-eslint/parser',
  extends:  [
    'plugin:@typescript-eslint/recommended',
    'prettier/@typescript-eslint',
    'plugin:prettier/recommended'
  ],
  parserOptions:  {
    ecmaVersion:  2018,
    sourceType:  'module'
  },
  // 其他配置
};
  1. 因为我使用了 TypeScript 所以 .eslintrc.* 配置项的值和 javascript 有点不一样,但是原理是一样的。如果你没有使用 TypeScript 那么到上面步骤就结束了。但是 VSCode 的 ESLint 插件没有天然支持 ts 文件,所以我们还必须自己建立一个设置文件。在项目根目录下新建 .vscode/settings.json 文件,内容如下:
    {
      "eslint.validate": [
        "javascript",
        "javascriptreact",
        { 
          "language": "typescript",
          "autoFix": true
        },
        { 
          "language": "typescriptreact",
          "autoFix": true
        }
      ]
    }
    

你就可以看到编辑器对代码有实时提示了。

强制校验和格式化

讲到这里两个工具配合使用已经讲好了,但是这些步骤都依赖于人工自觉,要做到一点点强制功能,我们就可以用到 husky lint-staged 来在 git commit 前强制代码格式化和代码校验。

  1. 安装

    $npm install --save-dev husky lint-staged
    
  2. 修改 package.json:

    {
      "name": "project-name",
      ...,
      + "husky": {
      +     "hooks": {
      +         "pre-commit": "lint-staged"
      +     }
      + },
      + "lint-staged": {
      +     "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
      +     "prettier --write",
      +     "eslint",
      +     "git add"
      +     ]
      + },
    }
    
  3. 那么在运行 git commit 时候,自动会先去运行 prettier --write 格式化代码,再运行 eslint 校验代码是否符合规范。这两步都通过后才会提交代码。如果任何一步失败,则会停止提交。

如果你使用方案一,lint-staged 配置的命令:

{
  "name": "project-name",
  ...,
  +  "husky": {
  +    "hooks": {
  +      "pre-commit": "lint-staged"
  +    }
  +  },
  + "lint-staged": {
  +   "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
  +     "prettier-eslint",
  +     "git add"
  +   ]
  + },
}

如果你使用了方案二中的 eslint-plugin-prettier,lint-staged 配置的命令:

{
  "name": "project-name",
  ...,
  +  "husky": {
  +    "hooks": {
  +      "pre-commit": "lint-staged"
  +    }
  +  },
  + "lint-staged": {
  +   "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
  +     "eslint --fix",
  +     "git add"
  +   ]
  + },
}

参考文献

  1. https://eslint.org/
  2. https://prettier.io/
  3. https://restishistory.net/blog/whats-the-difference-between-eslint-and-prettier.html

如果使用的是 TypeScript:

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

推荐阅读更多精彩内容