Code前端首页关于Code前端联系我们

我是如何在项目中使用 Lint 工具链的?

terry 3年前 (2023-09-10) 阅读数 469 #前端教程

我正在参加「掘金·启航计划」

demo 仓库地址:github.com/cheerioInf/…

为什么需要 Lint 工具链?

  1. 统一的代码风格:尤其是在多人合作的情景下,每个开发者都有自己的代码偏好,这可能导致整体项目代码风格混乱杂糅,难以阅读,Lint 工具可以统一代码风格,如缩进、命名风格、空格使用、每行最大字数等。
  2. 错误检查和预防:可以讲一些语法错误在开发阶段提前规避掉,还可以检测未使用的变量、使用未声明的变量等。

这两方面都能帮助我们提高整个项目等代码质量,提高项目的可维护性。

本次分享我们将围绕 ESLint、Prettier、StyleLint、commitLint 等主流 Lint 工具展开,配合 husky、lint-staged、VSCode 插件、Vite 生态搭建完整的 lint 工具链。

JS/TS 规范工具:ESLint

ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs.

ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误。

使用 ESLint 并不复杂,ESLint 是完全可插入的,主要通过配置文件对各种代码格式的规则 rules 进行配置,我们可以使用开源社区的一些成熟规范集,如 谷歌 JS 规范、standard JS、Airbnb 规范 等,也可以定制一套团队独有的代码规范。

初始化

通过 ESLint 官方的 cli 在**现有的脚手架项目(确保已经有一个 package.json 文件)**中进行初始化,首先安装 ESLint:

pnpm i eslint -D

接着执行 ESLint 的初始化命令:

npx eslint --init

我是如何在项目中使用 Lint 工具链的?我是如何在项目中使用 Lint 工具链的?

  • How would you like to use ESLint?
    • To check syntax only => 检查语法,如缺少分好、不正确的标识符等。
    • To check syntax and find problems => 检查语法、并发现错误,包括未使用的变量、使用未声明的变量等。
    • ✅ To check syntax, find problems, and enforce code style => 检查语法、发现错误,强制执行代码风格。
  • What type of modules does your project use?
    • ✅ Javascript module (import/export) => 选择 ESM 规范。
    • CommonJS (require/exports) => 选择 CJS 规范。
  • Which framework does your project use?
    • ✅ React
    • Vue
    • None of these
  • Where does your code run?
    • ✅ Browser
    • Node
  • How would you like to define a style for your project?
    • Use a popular style guide => 选择一些现有的 ESLint 规范。
    • ✅ Answer questions about your style => 通过回答问题确定自己的风格。
  • What format do you want your config file to be in?
    • ✅ Javascript
    • YAML
    • JSON

之后在根目录会生产 .eslintrc.cjs 文件,如下所示:

module.exports = {
  // 运行环境,环境并不互斥,可以一次定义多个环境
	"env": {
		"browser": true,
		"es2021": true
	},
  // 继承
	"extends": [
		"eslint:recommended", // eslint 推荐规则
		"plugin:@typescript-eslint/recommended", // ts 推荐规则
		"plugin:react/recommended" // react 推荐规则
	],
  // 解析器
	"parser": "@typescript-eslint/parser",
  // 解析器配置
	"parserOptions": {
		"ecmaVersion": "latest",
		"sourceType": "module" // 默认为 script,使用 esm 时需要设置为 module
	},
  // 插件
	"plugins": [
		"@typescript-eslint", // 添加 ts 的相关规则支持
		"react" // 添加 react 的相关规则支持
	],
  // 规则
	"rules": {
		"indent": [
			"error",
			"tab"
		],
		"linebreak-style": [
			"error",
			"unix"
		],
		"quotes": [
			"error",
			"double"
		],
		"semi": [
			"error",
			"always"
		]
	}
};

我们来了解一下这个配置文件里面会出现的几个字段。

配置解读

parser 解析器

ESLint 底层默认使用 Espree 来进行 AST 解析,其基于 Acron 来实现,不支持 TypeScript,因此需要引入其他的解析器完成 TS 的解析。

社区提供了 @typescript-eslint/parser,将 TS 代码转化为 Espree 能识别的格式,然后在 ESLint 下检查。

parserOptions 解析器配置

解析器格外配置,包含如 esmaVersion、sourceType、ecmaFeatures 等。

rules 代码规则

在 rules 对象中,key 一般为规则名,value 为具体的配置内容。

其中,off 表示关闭规则,warn 表示开启规则作为警告,违背规则后抛出 warning,不会导致程序退出,error 表示开启规则,违背规则后抛出错误,并退出程序。

plugins 插件

和上面提到的 ESLint 的默认 parser espree 不能直接解析 TypeScript 一样,ESLint 本身没有内置 TS 的代码规则,我们就需要添加插件来增加特定的规则,比如 @typescript-eslint/eslint-plugin。

引入后并没有默认开启这些规则,同样也需要我们去 rules 里面添加规则设置。

extends 继承

extends 相当于是继承另一份 ESLint 配置,主要为三种情况:

  1. 从 ESLint 本身继承:eslint:recommend
  2. 从第三方包继承
  3. 从插件中继承:plugin:react/recommended

env 和 globals

这两个配置分别代表运行环境和全局变量。JavaScript 生态有多种运行时、版本、扩展和框架。其中每一个都可以有不同的支持语法和全局变量,我们可以指定项目的运行环境:

module.export = {
  "env": {
    "browser": "true",
    "node": "true"
  }
}

指定之后便会启用浏览器和 Node.js 环境,这两个环境中的一些全局变量如 window、global 会同时启用。

有些全局变量是第三方库所声明,这里就需要在 globals 配置中声明全局变量:

  1. writable 表示变量可重写
  2. readonly 表示变量不可重写
  3. off 表示禁用该全局变量

以 jquery 为例:

module.exports = {
  "globals": {
    // 不可重写
    "$": false, 
    "jQuery": false 
  }
}

代码格式化工具:Prettier

虽然 ESLint 本身具备自动化修复的功能,但术业有专攻, ESLint 的主要优势在于代码风格的检查并给出提示,而在代码格式化层面,Prettier 更加专业,因此我们经常讲 ESLint 结合 Prettier 一起使用。

基础用法

首先安装 prettier:

pnpm i prettier -D

之后在根目录创建配置文件 .prettierrc.js,填入以下内容:

module.exports = {
  printWidth: 80, //一行的字符数,如果超过会进行换行,默认为80
  tabWidth: 2, // 一个 tab 代表几个空格数,默认为 2 个
  useTabs: true, //是否使用 tab 进行缩进,默认为false,表示用空格进行缩减
  singleQuote: false, // 字符串是否使用单引号,默认为 false,使用双引号
  semi: true, // 行尾是否使用分号,默认为true
  trailingComma: "none", // 是否使用尾逗号
  bracketSpacing: true // 对象大括号直接是否有空格,默认为 true,效果:{ a: 1 }
};

之后我们讲 prettier 集成到现有的 ESLint 工具中,首先安装两个包:

pnpm i eslint-config-prettier eslint-plugin-prettier -D

eslint-config-prettier 用来覆盖 ESLint 本身的规则配置,eslint-plugin-prettier 用来让 prettier 接管 eslint --fix 修复代码的能力。

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

在 extends 里面加入 prettier 以及 plugin:prettier/recommended 扩展。

"plugins": [
    "@typescript-eslint",
    "react",
    "prettier"
],

在 plugins 中加入 prettier 插件。

"rules": {
    "prettier/prettier": "error",
    // ...
}

在 rules 加入"prettier/prettier": "error" 开启 prettier 自动修复功能。

最后我们在 package.json 中定义脚本:

{
  "scripts": {
    "lint:script": "eslint --ext .js,.jsx,.ts,.tsx --fix --quiet ./src",
  }
}

之后在终端运行:

pnpm run lint:script

即可完成 ESLint 的规则检查以及 Prettier 的自动修复。

我们还需要在 rules 里面补充一个规则,防止我们在 jsx 文件中每次都要引入 react:

我是如何在项目中使用 Lint 工具链的?我是如何在项目中使用 Lint 工具链的?

rules: {
  // ...
  "react/react-in-jsx-scope": "off"
}

我们还可以在 VSCode 中安装 ESLint 和 Prettier 插件,在设置中开启 Format On Save:

我是如何在项目中使用 Lint 工具链的?我是如何在项目中使用 Lint 工具链的?

即可开启保存自动格式化功能。

在 vite 中接入 ESLint

我们也可以将 ESLint 接入 vite,在开发阶段进行 ESLint 扫描,将规范问题和源文件定位以命令行的形式展现出来。

首先安装 vite-plugin-eslint 插件:

pnpm i vite-plugin-eslint -D

之后我们在 vite.config.ts 中接入插件:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import viteEslint from "vite-plugin-eslint";

// https://vitejs.dev/config/
export default defineConfig({
	plugins: [react(), viteEslint()]
});

就完成了我们的配置。该插件会启动另外一个进程来进行 ESLint 的扫描工作,因此不会影响到项目的启动速度。

样式规范工具:Stylelint

一个强大的 CSS 规范工具,可帮助您避免错误并强制执行约定。

通过该样式规范工具,可以帮助解决常见的如重复的选择器、禁止使用指定的单位等等。

同样 Stylelint 在规范检查方面做的足够专业,而在代码格式化方面,我们依然需要 Prettier 的帮助。

首先,我们安装 Stylelint 及其相关的工具:

pnpm i stylelint stylelint-prettier stylelint-config-prettier stylelint-config-recess-order stylelint-config-standard stylelint-config-standard-scss -D

之后我们新建 .stylelintrc.js 配置文件:

module.exports = {
  // 注册 stylelint 的 prettier 插件
  plugins: ['stylelint-prettier'],
  // 继承一系列规则集合
  extends: [
    // standard 规则集合
    'stylelint-config-standard',
    // standard 规则集合的 scss 版本
    'stylelint-config-standard-scss',
    // 样式属性顺序规则
    'stylelint-config-recess-order',
    // 接入 Prettier 规则
    'stylelint-config-prettier',
    'stylelint-prettier/recommended'
  ],
  // 配置 rules
  rules: {
    // 开启 Prettier 自动格式化功能
    'prettier/prettier': true
  }
};

之后我们在添加脚本命令:

{
  "scripts": {
    // 整合 lint 命令
    "lint": "npm run lint:script && npm run lint:style",
    "lint:script": "eslint --ext .js,.jsx,.ts,.tsx --fix --quiet ./src",
    // stylelint 命令
    "lint:style": "stylelint --fix \"src/**/*.{css,scss}\""
  }
}

之后执行 pnpm run lint:style 即可完成对样式代码的规范检查和自动格式化。

也可以安装 VSCode 中 Stylelint 插件,实现在开发阶段感知问题,提前修复。

同样也可以在 vite 中接入 Styleint,在命令行体现规范问题,定位源文件。

pnpm i vite-plugin-stylelint -D
import viteStylelint from "vite-plugin-stylelint";

export default defineConfig({
	plugins: [
    // ...
		viteStylelint({
      // 排除检查
			exclude: ["node_modules/**", "dist/**"]
		})
	]
});

我是如何在项目中使用 Lint 工具链的?我是如何在项目中使用 Lint 工具链的?

Husky、lint-staged 的 git 提交工作流

Husky

上面我们配置的 ESLint、StyleLint 都只是将问题暴露,我们还需要实现在代码提交的时候,进行拦截检查,只有通过代码规范检查才允许正常提交代码,否则还是可能会导致线上代码出现不符合规定的情况。

社区中已经有对应的工具 Husky 来帮助我们解决这个问题了。

首先我们安装一下 Husky:

pnpm i husky -D

初始化 Husky(前提是你的项目得是一个 git 仓库):

我是如何在项目中使用 Lint 工具链的?我是如何在项目中使用 Lint 工具链的?

npx husky install

添加启动脚本:

{
  "scripts": {
    // 会在安装 npm 依赖后自动执行
    "prepare": "husky install"
  }
}

添加 husky 钩子:

npx husky add .husky/pre-commit "npm run lint"

该命令会在 .husky 目录下创建 pre-commit 文件,里面存放了在 git commit 前要执行的脚本,这里是在 git commit 前,对代码规范 lint 进行检查,检查通过之后才会提交代码。

lint-staged

如果我们仅仅只使用 husky 的话,npm run lint 是对仓库中的代码进行全量检查,也就意味着,当项目逐渐庞大起来,即使有很多文件并没有改动,但是每次提交时还是会进行规范化检查,就会增加提交的时间。

而 lint-staged 工具就是用来解决该问题的,可以实现只对暂存区的代码进行规范化检查,大大提高了提交代码的效率。

首先安装 lint-staged:

pnpm i lint-staged -D

之后在 package.json 中加入:

"lint-staged": {
  "**/*.{js,jsx,tsx,ts}": [
    "npm run lint:script",
    "git add ."
  ],
  "**/*.{scss}": [
    "npm run lint:style",
    "git add ."
  ]
},

最后,在 husky 的 pre-commit 中将原来的 npm run lint 脚本改为:

npx --no -- lint-staged

提交规范工具:commitlint

除了代码规范之外,代码提交信息规范也不可忽略。commitlint 能够帮助我们解决这个问题。

首先安装 commitlint 及其相关工具:

pnpm i commitlint @commitlint/cli @commitlint/config-conventional -D

然后我们新建 .commitlintrc.cjs 配置文件:

module.exports = {
  extends: ["@commitlint/config-conventional"]
};

一般来讲我们直接继承 commitlint/config-conventional 的规则就行了。

其提交信息由两部分组成:

// type 指提交的类型
// subject 指提交的摘要信息
<type>: <subject>

常用的 type 值包括如下:

  • feat:添加新功能。
  • fix:修复 Bug。
  • chore:一些不影响功能的更改。
  • docs:专指文档的修改。
  • perf:性能方面的优化。
  • refactor:代码重构。
  • test:添加一些测试代码等等。

最后我们将 commit-lint 集成到 husky 当中:

npx husky add .husky/commit-msg "npx --no-install commitlint -e $HUSKY_GIT_PARAMS"

我们随便输入一个 commit 信息,进行测试:

我是如何在项目中使用 Lint 工具链的?我是如何在项目中使用 Lint 工具链的?

会发现已经拦截成功了。

原文链接:https://juejin.cn/post/7247715962379173949 作者:cheerioInf

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门