这次你总搞清楚ESLint和Prettier咋玩的了吧

2,059 阅读10分钟

各位道友,今年第一次参加掘金人气榜单,活动时间12.20-12.30持续11天,每天可以投2票,打开:投票链接可以直接投票。

持续11天,每人每天默认可投2票,参与刷题再得4票,每投2票可以抽奖,据说每天好几万的奖品。

另外在PC端打开下面刷题(类似leetcode)链接(用掘金授权登录后,随便选一题点击最顶部的中间第一个运行按钮,不需要真^_^的刷题)可再得4票,累计一天最多可投6票。

参与刷题链接:www.marscode.cn/practice/8e…

下面开始我们的正题。

为什么需要 ESLint 和 Prettier?

在程序员的职业生涯中,编码规范一直是一个很重要的品格,你最终写出来代码,就像你精心设计的一套艺术品一样,让人看起来赏心悦目。如果你写出来的代码是一大坨💩,别人阅读和维护代码需要花费很多的时间。同样的别人写的代码是一坨💩,你也阅读起来也很头痛。比如下面的代码:

// 字符串用单引号,结尾不加;
var a = 'this is str'
// 字符串用双引号,结尾加;
var a = "this is str";

// 函数名后面不留空格
function sum() {
  ...
}

// if 后面添加空格
if () {
  ...
} else {
  ...
}

还有很多规范,可以参考这篇代码规范大全

在前端发展的前期阶段一般是团队统一制定规范约定代码格式,然后输出成文档,但团队成员无法在日常开发中去熟悉这些约定,大家入职了,都是立马投入一线战斗,谁没事闲的还去看看这些约定,直接一把梭就完事了,所以这些纸上谈兵的东西很多都是无法真正的落到实处的。

后来,聪明的前端大佬们就想出了 ESLintPrettier, 通过结合两者去实现团队的代码规范。这样大家写的代码规范都遵循同一套规则,不会相差十万八千里了。

好,废话就写到这里了。至少说清楚了为什么需要这两个东西了。

ESLint 与 Prettier 的功能和区别

用过这两个工具的人都知道,这个的规则集合有很多重复的,那我用一个不行吗?为什么我看绝大多数项目中都是两个一起用的呢?其实用一个也可以,但是两个配合使用效果更佳。下面我们来看看具体的对比。

核心功能对比

特性ESLintPrettier
主要用途检查代码的质量和遵循的规则,发现并修复错误。格式化代码,统一代码风格。
侧重点代码质量、逻辑问题(如未定义变量、无效代码)。代码格式(如换行、缩进、引号)。
规则类型提供丰富的可配置规则,支持代码质量和格式化规则。专注于格式化规则,偏向“无配置即最佳实践”。
可扩展性支持插件和自定义规则,覆盖全面的代码规范需求。配置较少,只针对格式问题调整。

功能范围

ESLint

  • 作用:分析代码,发现潜在的错误或不良实践。
  • 检查内容
    • 语法错误:例如未定义的变量、未使用的变量。
    • 逻辑问题:可能导致问题的代码(如条件总是为 true)。
    • 代码风格:例如缩进、行尾逗号、分号等。

Prettier

  • 作用:强制代码格式化,减少团队对代码风格的争论。
  • 格式化内容
    • 代码样式:例如缩进、单/双引号、逗号的使用等。
    • 结构:例如函数参数换行、对象属性排列。

配合使用

  • 避免冲突:ESLint 和 Prettier 可以整合,但要注意两者可能对同一问题(如缩进或引号风格)有不同的要求。
  • 整合工具
    • 使用 eslint-config-prettier:关闭 ESLint 中和 Prettier 冲突的规则,让 Prettier 专注于格式化。
    • 使用 eslint-plugin-prettier:将 Prettier 的规则集成到 ESLint 中,通过 ESLint 检查 Prettier 格式问题。

使用场景

  • 单独使用 ESLint:需要代码质量检查时。
  • 单独使用 Prettier:只想统一代码格式,不关心其他规则时。
  • 两者配合:想同时保证代码质量和风格统一。

最佳实践

以下是一个非常基础的项目示例,展示如何集成去 ESLintPrettier,并实现代码格式化功能。

项目结构

demo_01/
├── .eslintrc.json       # ESLint 配置文件
├── .prettierrc          # Prettier 配置文件
├── package.json         # 项目依赖和脚本
├── index.js             # 示例代码文件
└── .gitignore           # 忽略文件

初始化项目

创建项目

mkdir demo_01
cd demo_01
npm init -y

安装依赖

由于我装的依赖都是最新的,本人使用的node版本=v18.20.2,建议大家也使用18及以上版本。

eslint官网:eslint.org/docs/latest…

prettier官网:prettier.io/

安装 ESLint 和 Prettier

npm install eslint prettier eslint-config-prettier eslint-plugin-prettier --save-dev
  • 依赖说明
    • eslint:代码质量检查工具。
    • prettier:代码格式化工具。
    • eslint-config-prettier:关闭 ESLint 中和 Prettier 冲突的规则。
    • eslint-plugin-prettier:将 Prettier 作为 ESLint 的规则运行。

配置 ESLint 和 Prettier

配置 ESLint

由于我安装的"eslint": "^9.17.0",所以现在配置文件需要通过下方的方式:

创建 .eslint.config.mjs 文件:

import globals from 'globals';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import js from '@eslint/js';
import { FlatCompat } from '@eslint/eslintrc';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: js.configs.recommended,
  allConfig: js.configs.all,
});

export default [
  ...compat.extends('eslint:recommended', 'plugin:prettier/recommended'),
  {
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node,
      },
    },

    rules: {
      'prettier/prettier': 'error',
    },
  },
];

  • 解释
    • "plugin:prettier/recommended":集成 Prettier,并关闭冲突规则。
    • "prettier/prettier": "error":将格式化问题作为 ESLint 的错误提示。

如果你之前是用的.json文件,而且你的版本"^9.17.0",如果你创建的是.eslintrc.json文件,当你运行的时候会报错:

这时候你可以运行下面的命令,把.eslintrc.json的内容同步转化成.eslint.config.mjs文件

npx @eslint/migrate-config .eslintrc.json

配置 Prettier

创建 .prettierrc 文件:

{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2
}
  • 解释
    • semi:是否在行末添加分号。
    • singleQuote:是否使用单引号。
    • tabWidth:缩进的空格数。

添加示例代码

创建 index.js 文件,并写入格式不规范的代码:

function helloWorld () {
    console.log("Hello, world!")
  }

helloWorld()

添加脚本到 package.json

修改 package.json

{
  "scripts": {
    "lint": "eslint .", 
    "lint:fix": "eslint . --fix", 
    "format": "prettier --write ." 
  }
}
  • 解释
    • lint:运行 ESLint 检查代码。
    • lint:fix:运行 ESLint,并自动修复可修复的问题。
    • format:运行 Prettier 格式化代码。

运行 ESLint 和 Prettier

检查代码问题

npm run lint

可以发现,我们写的代码有问题了。

自动修复代码

npm run lint:fix

代码已经被修复了。

格式化代码

npm run format

跟运行npm run lint:fix同样的效果。

运行结果

运行 npm run lint:fixnpm run format 后,index.js 文件会被自动格式化为:

function helloWorld() {
  console.log('Hello, world!');
}

helloWorld();

配置保存时自动格式化(可选)

VS Code 集成

  1. 前置条件:安装 ESLintPrettier 插件。
  2. 共享配置:在 .vscode/settings.json 中添加以下内容:
// 注意此文件需要在项目的根目录下
{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "always",
    "source.fixAll.stylelint": "always"
  },
}

当你的同事下载了你这个项目代码的时候,会共享你这个配置文件。

保存文件时会自动格式化代码。这样就避免了遗留一大堆文件,手动去修复。

当然,你不想共享配置,可以在你自己的vscode工作区中单独去配置:

快捷键:cmd/ctrl + shift + p,搜索Open User Settings

在打开的文件中添加:

{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "always",
    "source.fixAll.stylelint": "always"
  },
}

保存文件时依然会自动格式化代码。

在 CI/CD 中集成

现在我们的配置最后是需要手动去运动npm run lint && npm run lint:fix && npm run format

如果说你提交的代码,没有经过lint的fix,保不齐代码格式就不对劲(一些坏小子搞破坏)。所以我们要有一种强制手段,在让他提交代码的时候自动执行上面的命令,保证提交到远程仓库的代码是符合我们的代码规范的。

这里我们需要使用husky配合lint-staged 工具实现我们的目标。

husky

官方文档:typicode.github.io/husky/get-s…

安装husky:

前置条件:首先需要初始化我们的git仓库

git init
# 本次安装版本:9.1.7
npm install husky -D

执行

npx husky init

package.json中自动生成执行钩子:

// package.json
"scripts": {
  // 自动生成钩子
  "prepare": "husky"
},

并且会在项目的根目录生成.husky文件

我们来测试一下,添加一条test脚本

{
  "scripts": {
    "test": "echo '放弃 commit 提交' && exit 2",
  },
}

执行

git add .
git commit -m "husky test"

执行结果

会发现最后我们的git commit 被终止了。

打开.husky/pre-commit文件,里面有一条命令:

npm run test

pre-commit文件里面的命令会在git commit执行命令,如果执行失败,就会导致终止提交。那么这样,我们是不是可以在这里把npm run lint放在这里去执行,从而自动去检测一些不符合规范的代码呢?

我们把npm run test替换成npm run lint,然后把代码保存自动格式化的代码注释掉,我们从新提交一下代码,会发现:

成功运行了npm run lint,并且终止了代码提交。

lint-staged

前面我们通过npm run lint的时候,其实是全量检测,如果我们的项目很庞大,每次commit的时候它都会把整个项目lint一遍,全量执行 ESLint 校验对于大型项目而言需要花费不少时间,理论上我们只需要确保提交到远程仓库的变更代码可以通过 ESLint 校验即可,而没有改动的代码则不需要进行 ESLint 校验。为此可以使用 lint-staged 工具。

lint-staged是一个在 git 暂存文件上(也就是被 git add 的文件)运行已配置的 linter(或其他)任务。它将使用暂存文件列表作为参数来运行任意 shell 任务,并根据指定的 glob 模式进行过滤。

安装:

npm install --save-dev lint-staged

在项目根目录添加.lintstagedrc.json文件,内容如下:

{
  "src/**/*.{js}": "eslint --fix"
}

这里表示只会lint src目录下的.js文件。

然后我们把pre-commit文件中的内容改成如下:

npx lint-staged

现在我们来测试一下。

在src下面创建index.js文件,内容如下:

function helloWorld()   {
  console.log('Hello, world!');
  return 'aaa'
}

helloWorld();

可以很明显的看到两处错误。

然后我们执行:

git add .
git commit -m "test"

此时再看index.js文件的内容,可以看到:

function helloWorld() {
  console.log('Hello, world!');
  return 'aaa';
}

helloWorld();

之前不规范的代码已经被完全修复了,并且成功提交了。

当我们的另一位同事clone我们的代码,并且运行npm i的时候,就会自动执行prepare:husky钩子,在本地生成.husky/_目录,由于.husky/pre-commit被提交到了远程仓库,因此克隆的时候会形成团队共享,不需要再执行 npx husky init操作。

src/index.js中随便写一些具备 ESLint 校验错误的代码并尝试提交,会发现配置的 Husky 和 Lint Staged 可以生效,因此在开发者不需要做任何配置的情况下,就生效了 Git 提交的 ESLint 校验功能。

至此,我们已经完整的通过ESlint和Prettier来规范我们的代码格式,然后通过husky和lint-staged去做强制格式化,防止不规范的代码被提交到仓库。一般一个规范的项目库都是通过这一套工具来搞。当然还有关于ts、react、vue等等对应的规则和不同的库,由于篇幅有限,我会另外开启新篇章来讲。

感谢耐心看完,祝您事业一路长虹!

代码参考地址:github.com/xiumubai/es…