一文搞懂eslint、prettier以及vscode插件之间的弯弯绕绕

246 阅读9分钟

前言

本来是写一篇笔记记录一下配置过程,但是看到两个同学收藏了就花了些时间充实了文章,有任何错误请在评论区留言。

第一步:创建一个新项目

使用npm init -y创建一个package.json文件,记录项目的信息。 在创建过程中会有一系列的选项,-y意味着所有选项均采用默认规则。

image.png 看到这个图片证明项目成功初始化了。

在项目里创建一个index.js文件,随便写几行不符合规则的代码。

image.png

文件夹

image.png

index.js代码

第二步 安装eslint
  1. 使用npm i eslint -D安装eslint。
  2. 在项目中初始化eslint配置。如果是在项目中局部安装eslint需要使用npx eslint --init,如果是全局安装可以使用eslint --init。在现在也就是2024年3月10日,使用上述命令控制台会提示,也可以使用npm init @eslint/config命令进行初始化配置。

image.png 我的eslint初始化配置如上,这个就根据实际情况进行选择。然后会产生一个.eslintrc.js文件。这个就是eslint配置文件。

image.png

文件夹情况

image.png

生成的.eslintrc.js情况

文件里的rules字段的就是eslint配置的规则。我们通过在文件里配置rules,就可以让eslint按照我们设置的规则进行检测。
在规则配置的时候 0 代表off关闭,1代表warn,2代表error。
"semi": 2,      // 不使用分号就报error错误          
"no-debugger": 1 //有debugger的时候就会报warn警告   

使用npx eslint index.js运行eslint检测我们的代码

image.png 我们可以看到

image.png 我们可以看到已经报错了和报警告了,因为咱们缺少分号和出现了debugger。
现在我们是在控制台里边,使用命令进行检测代码。我们同样可以使用eslint在命令行里修复我们的代码:npx eslint index.js --fix--fix参数就是修复代码。

image.png

修复后的代码

可以看到缺少的分号已经加上了。
第三步 vscode中eslint扩展插件

上述的操作都是在命令行里的操作,在编辑器里边没有任何的提示,并且修复代码和检测代码都需要在控制台输入命令,很不清晰,所以我们需要vscode层面的支持,实现vscode编辑器可以帮我们检测代码和修复代码,比如:代码检测就是代码不符合我们定制的规则要直接在代码工作区上画出波浪线修复代码就是我们保存代码的时候调用eslint的命令修复代码,这就要下载vscode扩展里的eslint插件,利用vscode插件将eslint和vscode连接起来,让vscode可以使用eslint的能力。

首先要下载的插件就是微软出品的ESLint插件(认准微软标识):

image.png

接下来打开vscode的设置文件settings.json:

image.png 然后再JSON文件里加入下边这段代码,注:JSON文件需要在文件内容的最外层加上一个一对{}。

  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true //当保存代码的时候开启eslint格式化功能
  },

接下来返回文件中当我们保存文件的时候,就会发现eslint就会按照我们的规则修复代码。

注:eslint能修复的就会修复,如缺少分号和使用单双引号等等,如果是涉及到一些逻辑的代码不会修复,会按照我们在.eslintrc中设置好的规则在我们代码编辑区,报错或者发出警告。如果我们在.eslintrc中设置"no-debugger":2 规则,eslint不会帮我们去掉debugger,而是会在代码上报错:

image.png

我们也可以使用eslint规范代码风格,如缩进,每行最大字符数等,但是eslint官网决定从v8.53.0起,Eslint中「代码风格相关规则」将被弃用。 这就不用纠结到底是使用eslint规范代码风格还是prettier来规范代码格式了。以后就无脑prettier。

第四步 安装prettier

eslint用来规范代码错误和代码质量,prettier用来规范代码风格,当多人一起开发项目的时候,规范一定的风格是有利于维护的。同时避免了多种风格破坏git diff的信息可读性 我们使用npm i prettier -D来安装,因为我们都是在编码阶段需要格式化和代码检查,安装开发依赖就足够了,也就是-D参数的意思,在生产环境这些包我们不需要安装。

image.png

安装完成之后,我们可以使用`npx prettier --write index.js`来格式化我们的代码,下图就是prettier把第一行代码的不规范缩进给去掉了。都变成顶格写的代码。

image.png

到这里有人就会奇怪了:我还没配置规则呢,prettier怎么就把代码缩进干掉了。这就和prettier的设计理念有关了,prettier官网宣称自己是一款固执己见的代码格式化工具,prettier已经内置了大部分的代码风格规则,只暴露出一部分必要的规则给用户配置,这样可以最大限度的控制代码风格,因为你可操作的空间太小了!甚至可以说如果所有的项目都普及了prettier,那么你阅读大洋彼岸的代码和阅读自己的代码差别不大,前提是你也使用prettier。
第五步 vscode中prettier扩展插件

prettier的vsocde插件也是为了将prettier的能力集成到vscode中,让我们程序员不用再控制台敲击命令调用prettier,而是保存代码的时候进行格式化代码。

image.png

安装这个插件并且在settings.json里边配置如下代码
  "editor.defaultFormatter": "esbenp.prettier-vscode",//表示编辑器默认格式化工具是prettier
  "editor.formatOnSave": true //开启编辑器保存格式化功能

这样就可以在保存的时候使用prettier进行格式化了。

冲突问题

eslint保存代码进行格式化,prettier保存代码进行格式化,保存代码的时候调用两种工具进行格式化,这就有可能造成格式化冲突。
原因:我们在使用eslint的时候很少去eslint的rules里边一条一条配规则,也就是这样:

image.png 很多时候我们都会使用npm下载开源的规范配置,使用eslint中的extends继承我们下载好的规范配置,比如这样:

image.png extends数组第一项是我们eslint初始化的时候,的推荐配置,第二项standard就是我们下载的开源规范配置,这个规范配置推荐使用单引号和不加分号
standard规范配置下载方式:npm install eslint-config-standard
standard规范配置引入方式:extends: ['standard']
我们在项目中可以继承多个规范,但是互相之间有冲突的话会有覆盖规则。这也是为了更好的扩展。

注:在 ESLint 中,当使用 extends 来继承多个配置时,确实可能会发生规则的覆盖。继承的配置会按照它们在 extends 数组中出现的顺序进行合并。如果多个配置中有相同的规则,那么后出现的配置中的规则会覆盖先出现的配置中的规则。

我们回到冲突话题,上边说到standard推荐使用单引号和不加分号,但是如果我们在.prettierrc.js中配置了使用双引号,加分号(不配置这条规则,prettier默认规则配置也是使用分号)。就会发生冲突了。会发现引号和分号会发生闪烁的效果,这是因为eslint先根据standard的规则配置进行格式化,使用单引号和去掉分号,而后prettier也进行了格式化使用双引号和加上分号,这就导致了闪烁。

(我是想把效果录制下来生成gif的,但是闪烁是在太快,录制软件帧数不够看不出效果)

解决方案

将prettier当做eslint的插件来使用,将prettier的规则插入到eslint规则中,禁用掉eslint里边与prettier冲突的规则。 重点是:

  1. 禁用掉eslint里冲突的规则
  2. 将prettier的规则插入到eslint中

这样既可以解决冲突,还可以

也可以让prettier借助eslint的规则实现:不满足prettier的规则就会在代码工作区显示warn和error。

prettier官方提供了两个工具:

  • eslint-config-prettier:一个规范,禁用eslint里冲突的规则
  • eslint-plugin-prettier:一个插件,将prettier作为规则插入到eslint里。 将两个工具按照如下方式进行配置就可以使用:
module.exports = {
     ......
  extends: ["eslint:recommended", "prettier"],//禁用冲突规则 eslint-config-prettier
  plugins: ["prettier"],//使用 eslint-plugin-prettier插件
  rules: {
    ......
    "prettier/prettier": "error",//规范prettier规则报error
  },
  ........
};
  • extends里边prettier相当于集成了我们上述提到的eslint-config-prettier的插件的规范。
  • plugins: ["prettier"]则是将eslint-plugin-prettier插件插入到eslint的插件系统中,将prettier集成到eslint中
  • "prettier/prettier": "error"意思是代码违反了prettier的规则,就会报error,也就是我们上述说的:

也可以让prettier借助eslint的规则实现:不满足prettier的规则就会在代码工作区显示warn和error。

这样一来就可以配置好eslint和prettier了。并且这一套下来就相当于配置好了带有prettier功能的,与prettier规则配置无冲突的eslint工具,这是也就无关紧要prettier的vscode插件,可以开启也可以关闭,因为我们eslint现在已经带有prettier的格式化效果了。

注:我们最终生效的是eslint的npm包+prettier的npm包+eslint的vscode插件,prettier的settings.json文件配置和vscode插件就显得很多余了。干掉也不会影响我们的格式化了。

文件配置
module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: ["eslint:recommended", "standard", "prettier"],
  overrides: [
    {
      env: {
        node: true,
      },
      files: [".eslintrc.{js,cjs}"],
      parserOptions: {
        sourceType: "script",
      },
    },
  ],
  plugins: ["prettier"],
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
  },
  rules: {
    "prettier/prettier": "error",
  },
};

module.exports = {
  printWidth: 80, //单行长度
  tabWidth: 2, //缩进长度
  useTabs: false, //使用空格代替tab缩进
  singleQuote: false, //使用单引号
  quoteProps: "as-needed", //仅在必需时为对象的key添加引号
  jsxSingleQuote: true, // jsx中使用单引号
  trailingComma: "all", //多行时尽可能打印尾随逗号
  bracketSpacing: true, //在对象前后添加空格-eg: { foo: bar }
  jsxBracketSameLine: true, //多属性html标签的‘>’折行放置
  arrowParens: "always", //单参数箭头函数参数周围使用圆括号-eg: (x) => x
  requirePragma: false, //无需顶部注释即可格式化
  insertPragma: false, //在已被preitter格式化的文件顶部加上标注
  proseWrap: "preserve", //不知道怎么翻译
  htmlWhitespaceSensitivity: "ignore", //对HTML全局空白不敏感
  vueIndentScriptAndStyle: false, //不对vue中的script及style标签缩进
  endOfLine: "lf", //结束行形式
  embeddedLanguageFormatting: "auto", //对引用代码进行格式化
};


{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
  },
}
待续

下一篇会讲eslint和webpack以及vite的关系及实践。