从零构建前端 Lint 工作流(2020手把手版)

选择性阅读
新手建议从头开始,都是手把手,按步骤配置一遍
想集成 VSCode 插件,自动提示/修复错误–>VSCode 集成 ESLint 检查
什么是代码检查
代码检查主要是用来发现代码错误、统一代码风格。
在 JavaScript 项目中,我们一般使用 ESLint 来进行代码检查,它通过插件化的特性极大的丰富了适用范围,搭配 typescript-eslint 之后,甚至可以用来检查 TypeScript 代码。
配置 ESLint
小试牛刀
新建一个文件夹,打开命令行, npm init -y 创建 package.json
安装依赖 npm install --save-dev eslint babel-eslint eslint-config-alloy
在项目根目录下创建一个 .eslintrc.js 或 .eslintrc.json 的配置文件:
// .eslintrc.js
module.exports = {
extends: [
‘alloy’,
],
};
在项目根目录下创建一个 index.js ,复制下面内容:
var myName = ‘Tom’;
console.log(My name is ${myNane});
在命令行输入 npx eslint index.js
// eslint 报错信息:
✖ 2 problems (2 errors, 0 warnings)
error Unexpected var, use let or const instead no-var
error ‘myNane’ is not defined no-undef
使用 npx eslint index.js --fix 自动修复某些规则
// 这时 var 变成了 let
// 还剩下一个无法自动修复的错误
✖ 1 problem (1 error, 0 warnings)
error ‘myNane’ is not defined no-undef
配合 TypeScript
由于 ESLint 默认使用 Espree 进行语法解析,无法识别 TypeScript 的一些语法,故我们需要安装 @typescript-eslint/parser,替代掉默认的解析器,别忘了同时安装 typescript:
npm install --save-dev typescript @typescript-eslint/parser
接下来需要安装对应的插件 @typescript-eslint/eslint-plugin 它作为 eslint 默认规则的补充,提供了一些额外的适用于 ts 语法的规则。
npm install --save-dev @typescript-eslint/eslint-plugin
修改配置文件
module.exports = {
extends: [
‘alloy’,
],
parser: ‘@typescript-eslint/parser’,
plugins: [’@typescript-eslint’],
rules: {
// 禁止使用 var
‘no-var’: “error”,
// 优先使用 interface 而不是 type
‘@typescript-eslint/consistent-type-definitions’: [
“error”,
“interface”
]
}
}
以上配置中,我们自定义了两个规则,其中 no-var 是 ESLint 原生的规则(我们刚刚已经用到了这个规则,它被包含在 alloy 中,此处会覆盖),@typescript-eslint/consistent-type-definitions 是 @typescript-eslint/eslint-plugin 新增的规则
规则的取值一般是一个数组(上例中的 @typescript-eslint/consistent-type-definitions),其中第一项是 off、warn 或 error 中的一个,表示关闭、警告和报错。后面的项都是该规则的其他配置。
如果没有其他配置的话,则可以将规则的取值简写为数组中的第一项(上例中的 no-var)。
::: warning 关闭、警告和报错的含义如下:

关闭:禁用此规则
警告:代码检查时输出错误信息,但是不会影响到 exit code
报错:发现错误时,不仅会输出错误信息,而且 exit code 将被设为 1(一般 exit code 不为 0 则表示执行出现错误)
:::

新建 index.ts 文件:
var myName = ‘Tom’;
console.log(My name is ${myNane});
console.log(My name is ${myName.toStrng()});
type Foo = {};
在命令行输入 npx eslint index.ts ,如下可以看到报错信息以及可修复项
1:1 error Unexpected var, use let or const instead no-var
2:27 error ‘myNane’ is not defined no-undef
4:6 error Use an interface instead of a type @typescript-eslint/consistent-type-definitions

✖ 3 problems (3 errors, 0 warnings)
2 errors and 0 warnings potentially fixable with the --fix option.
脚本命令检查整个项目
根目录新建一个src文件夹,将我们的 index.js 和 index.ts 放进去
在 package.json 中的 scripts 新增:
{
“scripts”: {
// 因为eslint不是全局安装的,所以要使用npx
“eslint”: “npx eslint src --ext .js,.ts,tsx”
// eslint 默认不会检查 .ts 后缀的文件,所以需要加上参数 --ext .ts
}
}
然后 npm run lint 就可以看到src下所有指定后缀文件的报错信息
推荐使用 AlloyTeam 的配置
上面手把手完成了 ESLint 的配置过程
有一定经验的推荐直接使用 AlloyTeam 实现可自定义拓展的 ESLint 规则
AlloyTeam/eslint-config-alloy 已经帮我们集成了各种技术栈
安装技术栈相关依赖
// Eslint
npm install --save-dev eslint babel-eslint eslint-config-alloy
// React
npm install --save-dev eslint babel-eslint eslint-plugin-react eslint-config-alloy
// Vue
npm install --save-dev eslint babel-eslint vue-eslint-parser eslint-plugin-vue eslint-config-alloy
// TypeScript
npm install --save-dev eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-alloy
// TypeScript React
npm install --save-dev eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-config-alloy
配置 .eslintrc.js 文件
/* .eslintrc.js */
module.exports = {
extends: [
‘alloy’, // 都需要
‘alloy/vue’, //vue项目需要
‘alloy/react’, //react项目需要
‘alloy/typescript’, //ts项目需要
],
env: {
// 你的环境变量(包含多个预定义的全局变量)
//
// browser: true,
// node: true,
// mocha: true,
// jest: true,
// jquery: true
},
globals: {
// 你的全局变量(设置为 false 表示它不允许被重新赋值)
//
// myGlobal: false
},
rules: {
// 自定义你的规则
}
};
eslint
VSCode 集成 ESLint 检查
在编辑器中集成 ESLint 检查,可以在开发过程中就发现错误,甚至可以在保存时自动修复错误,极大的增加了开发效率

.vscode/settings.json
{
// VSCode 中的 ESLint 插件默认是不会检查 .vue.ts.tsx 后缀的
“eslint.validate”: [
“javascript”,
“javascriptreact”,
“vue”,
“typescript”,
“typescriptreact”
],
// 开启保存时自动修复
“editor.codeActionsOnSave”: {
“source.fixAll.eslint”: true
},
// 指定VSCode用于IntelliSense(智能感知)的ts版本,将内置版本更换为工作区版本
“typescript.tsdk”: “node_modules/typescript/lib”
}
结合 Prettier 使用
Prettier 是一个代码格式化工具,相比于 ESLint 中的代码格式规则,它提供了更少的选项,但是却更加专业。

配置 Prettier
安装 Prettier
npm install --save-dev prettier
配置 .prettierrc.js 仅供参考:
// .prettierrc.js
module.exports = {
// 一行最多 100 字符
printWidth: 100,
// 使用 4 个空格缩进
tabWidth: 4,
// 不使用缩进符,而使用空格
useTabs: false,
// 行尾需要有分号
semi: true,
// 使用单引号
singleQuote: true,
// 对象的 key 仅在必要时用引号
quoteProps: ‘as-needed’,
// jsx 不使用单引号,而使用双引号
jsxSingleQuote: false,
// 末尾不需要逗号
trailingComma: ‘none’,
// 大括号内的首尾需要空格
bracketSpacing: true,
// jsx 标签的反尖括号需要换行
jsxBracketSameLine: false,
// 箭头函数,只有一个参数的时候,也需要括号
arrowParens: ‘always’,
// 每个文件格式化的范围是文件的全部内容
rangeStart: 0,
rangeEnd: Infinity,
// 不需要写文件开头的 @prettier
requirePragma: false,
// 不需要自动在文件开头插入 @prettier
insertPragma: false,
// 使用默认的折行标准
proseWrap: ‘preserve’,
// 根据显示样式决定 html 要不要折行
htmlWhitespaceSensitivity: ‘css’,
// 换行符使用 lf
endOfLine: ‘lf’
};
VSCode 集成 Prettier
在 .vscode/settings.json 中添加配置:
{
// 保存时自动格式化所有支持文件 javascript/javascriptreact/typescript/typescriptreact/json/graphql
“editor.formatOnSave”: true,
“editor.defaultFormatter”: “esbenp.prettier-vscode”,
}
这时我们保存文件的时候,已经可以自动格式化了
也可以指定格式化文件类型:
{
// Set the default
“editor.formatOnSave”: false,
// Enable per-language
“[javascript]”: {
“editor.defaultFormatter”: “esbenp.prettier-vscode”,
“editor.formatOnSave”: true
}
}
Git 代码预检
ESLint、Prettier
实现过程
待提交的代码
git add 添加到暂存区
执行 git commit(这时进行代码预检)
husky注册在git pre-commit的钩子调起 lint-staged
lint-staged 取得所有被提交的文件依次执行写好的任务
如果有错误(没通过ESlint检查)则停止任务,等待下次commit,同时打印错误信息
成功提交后,git push推送到远程库
什么是 git hook
git hook
cd .git/hooks
ls -l
// 打印如下:
total 96
-rwxr-xr-x 1 zzc staff 478 10 21 2019 applypatch-msg.sample
-rwxr-xr-x 1 zzc staff 896 10 21 2019 commit-msg.sample
-rwxr-xr-x 1 zzc staff 3327 10 21 2019 fsmonitor-watchman.sample
-rwxr-xr-x 1 zzc staff 189 10 21 2019 post-update.sample
-rwxr-xr-x 1 zzc staff 424 10 21 2019 pre-applypatch.sample
-rwxr-xr-x 1 zzc staff 1638 10 21 2019 pre-commit.sample
-rwxr-xr-x 1 zzc staff 1348 10 21 2019 pre-push.sample
-rwxr-xr-x 1 zzc staff 4898 10 21 2019 pre-rebase.sample
-rwxr-xr-x 1 zzc staff 544 10 21 2019 pre-receive.sample
-rwxr-xr-x 1 zzc staff 1492 10 21 2019 prepare-commit-msg.sample
-rwxr-xr-x 1 zzc staff 3610 10 21 2019 update.sample
.sample
husky 注册 git hook
Requires Node >= 10 and Git >= 2.13.0.

husky 新老版本的配置方式和使用变化较大,老版本请自行升级,详见 husky
安装 husky
npm install husky --save-dev
编辑 package.json 文件:
{
“husky”: {
“hooks”: {
“pre-commit”: "eslint src//*.js"
}
},
}
尝试 git commit 提交,就会先执行 eslint src/
/*.js ,代码没有问题才会被真正提交
这样每次提交代码, eslint 都会检查所有文件,如果报错过多,一定会崩溃
lint-staged 只 Lint 改动代码
lint-staged requires Node.js version 10.13.0 or later.

v10.0.0 以后对原始暂存文件的任何新修改都将自动添加到提交中。如果您的任务以前包含一个git add步骤,请删除此步骤,同时运行多个git操作通常会导致错误,详见 lint-staged
安装 lint-staged
npm install lint-staged --save-dev
新增 package.json 配置:
{
“lint-staged”: {
“src/**/*.js”: “eslint”
}
}
如此 husky 只负责注册 git hook ,后续操作交给 lint-staged ,只对改动的文件执行任务,而且可以很方便
地配置多条命令:

{
“husky”: {
“hooks”: {
“pre-commit”: “lint-staged”
}
},
“lint-staged”: {
"src//*.js": [“eslint --fix”, “prettier --write”]
}
}
如上,我们提交代码之前,程序会自动修复 eslint 配置,格式化 prettier 配置
几点建议
建议代码提交只做检查和测试,拦截问题代码比较好,还是在保存时,自动修复 eslint、prettier 配置,而且大部分还需要手动修复才行
实在紧急,也可通过 git commit -m -n “跳过代码代码预检” 跳过检查,慎用
和构建有关的包建议使用 --save-dev 安装在项目内部
老版本 husky lint-staged 配置都放在 package.json 中,现在 eslint prettier husky lint-staged 都支持多种后缀配置文件,建议采用 .js 统一格式,也方便拓展:
统一配置文件格式
// .eslintrc.js
module.exports = {
extends: [
‘alloy’,
],
};
// .prettierrc.js
module.exports = {
// 一行最多 100 字符
printWidth: 100,
// 使用 4 个空格缩进
tabWidth: 4,
// …
};
// .huskyrc.js
module.exports = {
‘hooks’: {
‘pre-commit’: “lint-staged”
}
}
// .lintstagedrc.js
module.exports = {
"src/
/.{js,ts}": “eslint”
}
拓展示例
.huskyrc.js
// 数组方式配置多条命令
const tasks = arr => arr.join(’ && ')
module.exports = {
‘hooks’: {
‘pre-commit’: tasks([
‘npm run lint’,
‘npm test’
])
}
}
.lintstagedrc.js
module.exports = {
// 如果超过10个暂存文件,则在整个存储库上运行eslint
'**/
.js?(x)’: (filenames) =>
filenames.length > 10 ? ‘eslint .’ : eslint ${filenames.join(' ')},
.css": “stylelint”,
"
.scss”: “stylelint --syntax=scss”,
// 对ts文件运行tsc,但不传递任何参数
‘**/*.ts?(x)’: () => ‘tsc -p tsconfig.json --noEmit’
}

你可能感兴趣的:(前端,前端·)