⚙️ 使用 Prettier、AirBnB Styleguide、Husky 和 ​​lint-staged 将 Angular 应用迁移到 ESLint

2025-06-08

⚙️ 使用 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'];
Enter fullscreen mode Exit fullscreen mode

如果我们尝试使用 ESLint 格式化此字符串,它只会在控制台中引发错误:

eslint example.ts --fix

output:
error    This line has a length of 105. Maximum allowed is 80
Enter fullscreen mode Exit fullscreen mode

这个例子表明,linters 并不总是能帮助格式化代码。因此,开发人员会根据个人情况,自行以不同的方式格式化代码。

如果我们使用 Prettier 保存并格式化文件,则该字符串将被重新打印为:

const example = [
  '1',
  'long string',
  'another string',
  0123456789,
  '1',
  'long string',
  'another string'
];
Enter fullscreen mode Exit fullscreen mode

Prettier 在整个代码库中提供一致的格式化样式。因此,它必须与 ESLint 一起使用。但是,我们必须对它们进行配置,以确保它们不会相互冲突。

配置 ESLint

ESLint 与解析器协同工作,将代码转换为AST(抽象语法树),用于软件处理和插件,其中包含规则,例如,用于 linting TypeScript 的推荐规则或来自样式指南的规则。

依赖项安装

要将 Angular 应用程序迁移到 ESLint,我们将使用以下依赖项:

  • @angular-eslint/builder — Angular CLI Builder 使用标准命令为 Angular 应用程序运行 ESLint  ng 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
Enter fullscreen mode Exit fullscreen mode

目前,Codelyzer 基本 TSLint 配置中的 ESLint 规则并非全部在@typescript-eslint和 中都有对应版本@angular-eslint,但大多数规则已经存在。您可以在官方 monorepos Angular ESLintTypeScript 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"]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

您可以使用不同的扩展创建配置: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"
    ]
  }
},
Enter fullscreen mode Exit fullscreen mode

基本设置已完成。现在,要启动 ESLint,只需运行ng lint

安装其他 ESLint 插件

如果您想要为 ESLint 安装另一个插件,例如,为了检查 Jasmine 规范文件,请安装适当的 npm-package:

npm install eslint-plugin-jasmine --save-dev
Enter fullscreen mode Exit fullscreen mode

并在“覆盖”中为具有以下扩展名的文件添加新的规则块*.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'
    }
  }
],
Enter fullscreen mode Exit fullscreen mode

您可以通过这种方式将任何插件添加到您的 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
Enter fullscreen mode Exit fullscreen mode

['*.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: {
        ...
      }
    },
    ...
  ]
}
Enter fullscreen mode Exit fullscreen mode

如果您想使用另一种样式指南,请在“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,
          }
        ]
      }
    },
    ...
  ]
}
Enter fullscreen mode Exit fullscreen mode

配置 Prettier

要在 ESLint 配置中添加 Prettier,我们需要安装 Prettier 本身、带有 Prettier 规则的插件以及关闭所有与 Prettier 冲突的规则的配置:

npm i prettier eslint-config-prettier eslint-plugin-prettier --save-dev
Enter fullscreen mode Exit fullscreen mode

在 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: {
        ...
      }
    },
    ...
  ]
}
Enter fullscreen mode Exit fullscreen mode

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
};
Enter fullscreen mode Exit fullscreen mode

如果您希望单独运行,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,
  },
Enter fullscreen mode Exit fullscreen mode

您还可以为 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
Enter fullscreen mode Exit fullscreen mode

在以下位置添加此插件的新设置package.json

"scripts": {
  ...,
},
"husky": {
  "hooks": {
    "pre-commit": "lint-staged --relative"
  }
},
"lint-staged": {
  "*.{js,ts}": [
     "eslint --fix"
  ]
},
Enter fullscreen mode Exit fullscreen mode

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
PREV
Django Rest 自定义用户模型和身份验证问题
NEXT
在一页纸上从头理解 React Redux