⚙️ 使用 Prettier、AirBnB Styleguide、Husky 和 lint-staged 将 Angular 应用迁移到 ESLint
如您所知,Palantir 决定弃用 TSLint,并专注于改进 ESLint 中的 TypeScript 支持,以避免开发类似的工具。
虽然 Angular 10不会迁移到 ESLint,但我决定将一些项目迁移到 ESLint,同时修改代码风格指南并添加一些新工具。这篇文章将介绍如何将 Angular TypeScript 应用从 TSLint 迁移到 ESLint、添加 Prettier、配置 Git hooks 以及使用 VS Code。
Prettier 和 ESLint
ESLint 是一个静态代码分析工具。ESLint 中的规则分为两类:
- 格式化——以一致的风格转换代码:字符串长度、逗号、分号等。
- 代码质量——搜索并修复问题代码模式:不必要的代码、错误。
Prettier 是一个固执己见的代码格式化程序,无需任何配置即可在保存文件时自动格式化代码。
我感兴趣的问题是:如果 ESLint 本身就能搞定所有事情,为什么还需要将 Prettier 与 ESLint 结合使用?答案很简单——Prettier 的代码格式化效果更好。它删除所有格式,并以一致的样式重新生成代码。这使得开发人员无需再费心格式化代码,也不必在代码审查时浪费时间讨论代码风格。
例如,我们有这样一长串代码:
const example = ['1', 'long string', 'another string', 0123456789, '1', 'long string', 'another string'];
如果我们尝试使用 ESLint 格式化此字符串,它只会在控制台中引发错误:
eslint example.ts --fix
output:
error This line has a length of 105. Maximum allowed is 80
这个例子表明,linters 并不总是能帮助格式化代码。因此,开发人员会根据个人情况,自行以不同的方式格式化代码。
如果我们使用 Prettier 保存并格式化文件,则该字符串将被重新打印为:
const example = [
'1',
'long string',
'another string',
0123456789,
'1',
'long string',
'another string'
];
Prettier 在整个代码库中提供一致的格式化样式。因此,它必须与 ESLint 一起使用。但是,我们必须对它们进行配置,以确保它们不会相互冲突。
配置 ESLint
ESLint 与解析器协同工作,将代码转换为AST(抽象语法树),用于软件处理和插件,其中包含规则,例如,用于 linting TypeScript 的推荐规则或来自样式指南的规则。
依赖项安装
要将 Angular 应用程序迁移到 ESLint,我们将使用以下依赖项:
@angular-eslint/builder
— Angular CLI Builder 使用标准命令为 Angular 应用程序运行 ESLintng lint
,@angular-eslint/eslint-plugin
— 带有用于检查 Angular 应用程序规则的插件,@angular-eslint/template-parser
— 解析器,与它结合,@angular/compiler
可以编写和使用规则来检查 Angular 模板,@angular-eslint/eslint-plugin-template
— 插件,与 结合@angular-eslint/template-parser
,运行规则来检查 Angular 模板,@typescript-eslint/parser
— 用于解析 TypeScript 代码的插件,@typescript-eslint/eslint-plugin
— 插件,运行规则来检查 TypeScript。
要安装它们,只需运行:
ng add @angular-eslint/schematics
目前,Codelyzer 基本 TSLint 配置中的 ESLint 规则并非全部在@typescript-eslint
和 中都有对应版本@angular-eslint
,但大多数规则已经存在。您可以在官方 monorepos Angular ESLint和TypeScript ESLint中跟踪规则开发的当前状态。
配置
我们已经安装了 lint Angular 应用所需的一切,现在我们可以开始配置 ESLint 了。让我们.eslintrc.js
在应用根目录创建一个配置文件,并添加Angular ESLint 的推荐设置:
module.exports = {
root: true,
overrides: [
{
files: ["*.ts"],
parserOptions: {
project: [
"tsconfig.*?.json",
"e2e/tsconfig.json"
],
createDefaultProgram: true
},
extends: ["plugin:@angular-eslint/recommended"],
rules: {
...
}
},
{
files: ["*.component.html"],
extends: ["plugin:@angular-eslint/template/recommended"],
rules: {
"max-len": ["error", { "code": 140 }]
}
},
{
files: ["*.component.ts"],
extends: ["plugin:@angular-eslint/template/process-inline-templates"]
}
]
}
您可以使用不同的扩展创建配置:JS、JSON 和 YAML。在 JavaScript 中,您可以添加注释。
plugin:@angular-eslint/recommended
包含三个插件的规则:@typescript-eslint/eslint-plugin
、@angular-eslint/eslint-plugin
和@angular-eslint/eslint-plugin-template
。
更新 ng lint 命令
我们还需要更新要运行的ng lint
命令:angular.json
@angular-eslint/builder
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.component.html"
]
}
},
基本设置已完成。现在,要启动 ESLint,只需运行ng lint
。
安装其他 ESLint 插件
如果您想要为 ESLint 安装另一个插件,例如,为了检查 Jasmine 规范文件,请安装适当的 npm-package:
npm install eslint-plugin-jasmine --save-dev
并在“覆盖”中为具有以下扩展名的文件添加新的规则块*.spec.ts
:
overrides: [
...,
{
files: ['src/**/*.spec.ts', 'src/**/*.d.ts'],
parserOptions: {
project: './src/tsconfig.spec.json',
},
// Jasmine rules
extends: ['plugin:jasmine/recommended'],
// Plugin to run Jasmine rules
plugins: ['jasmine'],
env: { jasmine: true },
// Turn off 'no-unused-vars' rule
rules: {
'@typescript-eslint/no-unused-vars': 'off'
}
}
],
您可以通过这种方式将任何插件添加到您的 ESLint 配置中。
添加样式指南规则
为了获得更好的代码库一致性,让我们从流行的样式指南之一中选择并添加到 ESLint 配置规则中:
- AirBnB:这三个中最受欢迎且最严格,要求使用逗号和分号,
- Google:与 AirBnB 有很多共同之处,但不那么严格,需要 JSDoc。
- StandartJS:禁止使用尾随逗号和分号。
选择更符合团队需求的样式指南。您可以在一个项目中尝试每种样式指南,查看 Linter 工具显示的错误,并决定采用哪些规则。
选择 TypeScript 实现样式指南规则,因为 JavaScript 规则可能与 TypeScript 不兼容。
例如,让我们从 AirBnB Styleguide 中添加 ESLint 配置规则。为此,我们需要安装包含 AirBnB 规则的配置,以便 TypeScript 和插件能够使用 import/export 语法:
npm install eslint-plugin-import eslint-config-airbnb-typescript --save-dev
['*.ts']
为了不更改顶级设置,请在“overrides”属性的规则块中添加 AirBnB Styleguide 规则:
module.exports = {
...,
overrides: [
{
files: ["*.ts"],
parserOptions: {
project: [
"tsconfig.*?.json",
"e2e/tsconfig.json"
],
createDefaultProgram: true
},
extends: [
"plugin:@angular-eslint/recommended",
// AirBnB Styleguide rules
'airbnb-typescript/base'
],
rules: {
...
}
},
...
]
}
如果您想使用另一种样式指南,请在“overrides”属性中创建一个新的规则块,其中包含样式指南规则和必要的解析器,以便像示例中那样运行它们。
规则定制
如果您想关闭或重新定义某些规则,您可以在“规则”属性中进行操作:
module.exports = {
...,
overrides: [
{
files: ["*.ts"],
parserOptions: {
project: [
"tsconfig.*?.json",
"e2e/tsconfig.json"
],
createDefaultProgram: true
},
extends: [
"plugin:@angular-eslint/recommended",
// AirBnB Styleguide rules
'airbnb-typescript/base'
],
rules: {
// Custom rules
'import/no-unresolved': 'off',
'import/prefer-default-export': 'off',
'class-methods-use-this': 'off',
'lines-between-class-members': 'off',
'@typescript-eslint/unbound-method': [
'error',
{
ignoreStatic: true,
}
]
}
},
...
]
}
配置 Prettier
要在 ESLint 配置中添加 Prettier,我们需要安装 Prettier 本身、带有 Prettier 规则的插件以及关闭所有与 Prettier 冲突的规则的配置:
npm i prettier eslint-config-prettier eslint-plugin-prettier --save-dev
在 ESLint 配置“overrides”中,在带有扩展名的文件规则块中“extends”属性的底部.ts
添加 Prettier 设置:
module.exports = {
...,
overrides: [
{
files: ["*.ts"],
parserOptions: {
project: [
"tsconfig.*?.json",
"e2e/tsconfig.json"
],
createDefaultProgram: true
},
extends: [
"plugin:@angular-eslint/recommended",
// AirBnB Styleguide rules
'airbnb-typescript/base',
// Settings for Prettier
'prettier/@typescript-eslint',
'plugin:prettier/recommended'
],
rules: {
...
}
},
...
]
}
Prettier 的配置应始终位于“extends”属性的底部,以关闭所有可能与 Prettier 冲突的先前规则。
prettier/@typescript-eslint
关闭可能@typescript-eslint
与 Prettier 冲突的规则,并plugin:prettier/recommended
执行三件事:
- 启用
eslint-plugin-prettier
, - 将规则标记
prettier/prettier
为"error"
, - 添加 Prettier 格式规则
eslint-config-prettier
。
更漂亮的配置
Prettier 无需配置即可格式化文件,但为了方便 AirBnB 代码引导,我们需要指定一些设置。.prettierrc.js
在应用程序根文件夹中创建:
module.exports = {
trailingComma: "all",
tabWidth: 2,
semi: true,
singleQuote: true,
bracketSpacing: true,
printWidth: 100
};
如果您希望单独运行,ESLint 和 Prettier 都会使用此配置。您可以使用 Prettier 本身prettier --write .
或 VS Code 的 Prettier 插件来格式化代码。
配置 VS Code
VS Code 可以高亮显示 ESLint 发现的错误,并在保存文件时进行修复。要启用此功能,请为 VS Code 安装ESLint 插件,并创建一个包含工作区配置的文件.vscode/settings.json
:
"eslint.validate": [ "javascript", "typescript", "html"],
"eslint.options": {
"extensions": [".js", ".ts", "html"]
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
},
您还可以为 VS Code 安装Prettier 插件,以使用 Prettier 格式化文件shift + option + f
。
配置 Git Hooks
Git Hooks 是 Git 在某些事件上调用的脚本:提交、推送、接收。
使用 Hooks,我们可以在创建提交时运行 lint 来减少拉取请求中的错误。为了更好地使用 Git Hooks,请安装Husky,并仅对暂存文件进行 lint(对于大型项目来说,lint 可能非常耗时,因此有必要使用lint-staged ) :
npm i husky lint-staged --save-dev
在以下位置添加此插件的新设置package.json
:
"scripts": {
...,
},
"husky": {
"hooks": {
"pre-commit": "lint-staged --relative"
}
},
"lint-staged": {
"*.{js,ts}": [
"eslint --fix"
]
},
Lint-staged 向调用的命令发送暂存文件数组。ng lint
它无法接受文件数组,因此必须编写额外的处理程序脚本才能使用它。或者,我们可以像本例一样直接运行 ESLint。您可以将此解决方案用于预提交,以及ng lint
在 CI 管道等环境中对项目的所有文件进行 lint 操作。
最后的想法
Angular ESLint 的未来版本将实现开箱即用。目前,配置 ESLint 需要一些额外的操作,部分规则在 ESLint 中尚无对应规则,而且 Angular ESLint Monorepo 目前处于 Alpha 版本。因此,是否迁移到 ESLint 完全取决于您。
但是,代码指南、附加规则、Prettier、Husky 和 lint-staged 需要自行安装。希望本文能帮助您理解这些工具是如何协同工作的。您可以在Github上找到已配置好的 Angular 项目。
设置 Linters 看似简单,但实际上包含一些重要的组织问题:选择哪种样式指南、插件包含哪些规则以及它们如何协同工作。花时间进行这些工作非常值得,因为它可以节省大量在代码审查中讨论代码风格的时间,确保代码库的一致性,并减少拉取请求中发送的错误数量。
感谢您的阅读!如果您有任何问题或补充,请随时留言。
鏂囩珷鏉ユ簮锛�https://dev.to/bzvyagintsev/migrate-angular-app-to-eslint-with-prettier-airbnb-styleguide-husky-and-lint-staged-862