如何为你的 React 应用设置 ESLint 和 Prettier
构建高质量的应用程序具有挑战性,原因有很多:
- 代码库越大,维护起来就越困难。
- 开发人员有不同的编码方式,这可能会让你感到困惑并减慢你的速度。
- JavaScript 语言乍一看很容易学,但实际操作起来却并非易事。你可能会掉入一些常见的陷阱。React(或任何其他前端库/框架)也是如此。
- ETC。
如今,许多工具可以帮助我们编写高质量的代码,并确保我们的应用程序不会崩溃。您可能首先会想到Jest、React Testing Library或Cypress之类的测试工具,但在编写测试之前,您可以使用linter为您的应用程序添加第一层安全保障。
检查你的代码
Linter会静态分析你的代码。这意味着它会检查代码而不执行它。但你可能会想,为什么要使用 Linter?因为你可以在编写糟糕代码的同时构建应用程序。因此,拥有一个能够发现常见错误和不良做法的工具至关重要。
Linter 最厉害的地方在于它能发现代码中看似不靠谱的潜在错误。例如,这里有一个 for 循环,乍一看,它会输出 0 到 4 之间的数字:
for (var i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 1000);
}
然而,它打印了五次5。很奇怪吧?这背后的原因是var关键字 是函数作用域的。由于这里没有函数,i将会是一个全局变量。因此,当第一个setTimeout的回调函数运行完毕时,循环就已经执行完毕,所以 的最后一个值i是 5。
您可以使用块范围let的关键字来修复此行为:
for (let i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 1000);
}
这一次,每次迭代都有自己的i变量,并且没有全局声明。
如果你在开发生涯中至少遇到过一次,几乎不可能猜到这里会发生什么。但是 Linter 可以!它会发现你var在 for 循环中使用了该关键字。在这个循环中,你使用的函数引用了其作用域之外的变量,这似乎是一个不好的做法。因此,它会向你抛出一个错误,你就知道该怎么做了。
ESLint
现在您已经了解了为什么检查代码的重要性,让我们来了解一下ESLint。它是一个开源项目,最初由Nicholas C. Zakas创建,为 JavaScript 提供了一个可插入的 linting 实用程序。
基本上,ESLint 会解析您的代码,对其进行分析,并运行 linting 规则。这些规则可能会触发警告或错误,让您知道代码是否正确。
例如,一个常用的规则是no-undef:它确保你的代码中没有任何未声明的变量。如果使用no-undef,以下代码将是错误的:
// ❌ Oops, what is add?
const result = add(1, 2);
确实如此。ESLint 无法识别add引用,因此会报错。你需要显式声明add来更正它:
// ✅ Correct
function add() {}
const result = add(1, 2);
安装 ESLint
您可以通过两种不同的方式安装 ESLint:
- 全球范围内:
npm install eslint -g - 关于一个项目:
npm install eslint --save-dev
我建议你直接在项目中安装 ESLint。事实上,如果你全局安装它,ESLint 可能会与你的其他项目或其他开发者发生冲突(并引发“它在我的机器上可以正常工作!”的问题)。
注意:您还可以使用VSCode 的 ESLint 扩展。它可以通过直接在代码中突出显示错误和警告来极大地改善您的开发人员体验。
配置 ESLint
ESLint 的优点在于它高度可配置。你只需要.eslintrc在项目根目录创建一个文件,然后就可以对任何你想要的文件运行 ESLint。
注意:也可以在package.json文件中定义 ESLint 配置。只需将配置对象放入eslintConfig键中即可。
此配置文件采用 JSON 对象的形式。您可以指定许多选项来实现此目的:
解析器选项
parserOptions :告诉 ESLint 您希望它如何解析代码。大多数情况下,您可以使用键指定要使用的 ECMAScript 版本(ES6、ES2018 等)。在这里,您还可以通过设置为 来告诉ESLint是否使用 ECMAScript 模块(和)。ecmaVersionimportexportsourceTypemodule
环境
environment定义您正在使用的预定义全局变量。例如,Jest 允许您在测试文件中使用全局变量,例如describe、it或test。但是,如果您没有明确告知,ESLint 将无法知道这些变量所引用的内容。为此,请设置jest为true。
全局变量
有时你可能会自己声明全局变量。然后,你需要将它们添加到此对象中。
插件
基本上,插件是一组与同一主题相关的 ESLint 规则。例如,eslint-plugin-react包含许多与 React 相关的规则。
注意:如果您希望规则正常工作,则必须将插件安装为开发依赖项。
规则
这些就是我们之前讨论过的 linting 规则。每条规则都有一个值,表示off是否要禁用该规则、warn是否显示警告或error是否抛出错误。
延伸
允许你从其他配置扩展你的配置文件。Create React Appreact-app提供了一个流行的配置扩展工具。此外,你还可以使用流行的样式指南,例如Airbnb、Google或Standard的样式指南。extends
内联配置
您可以使用特殊注释内联修改 ESLint 的配置。例如,您可以对与 相关的错误代码执行以下操作no-undef:
// eslint-disable-next-line
const result = add(1, 2);
这样,ESLint 就不会再抱怨了。
不过,请谨慎使用!每次 ESLint 发现错误就禁用它并不是一个好主意。这通常意味着你的代码有问题。
ESLint 命令行界面
ESLint 有一个命令行工具来检查文件的错误。你可以在 ESLint 的文档中找到所有选项。你最常用的选项是“--fix在 ESLint 可以修复文件时进行修复”的选项。例如,以下命令会检查代码库中存在的每个文件:
eslint .
然后您可以在package.json文件中包含这些脚本:
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint --fix ."
}
}
你可以通过命令使用这些脚本npm run。其中一个脚本只会对代码库进行 lint 操作,而另一个脚本则会尝试修复所有可以修复的问题。
ESLint 配置示例
以下是一个文件示例.eslintrc:
{
"env": {
"commonjs": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2020
},
"rules": {
"no-console": "error"
}
}
在此配置中,我们:
- 扩展
eslint:recommended配置 - 告诉 ESLint 我们将使用 CommonJS 全局变量(
require而不是import) - 指定我们将使用 2020 版 ECMAScript 语法编写 JavaScript
- 禁止使用
console.log。
这是另一个 ESLint 配置:
{
"env": {
"browser": true,
"jest": true,
"es6": true
},
"plugins": ["import"],
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"rules": {
"no-console": "warn",
"no-eval": "error",
"import/first": "error"
}
}
此 ESLint 配置满足以下要求:
- 包含推荐的 ESLint 规则
- 包括
jest的、es6的和browser的全局变量 - 不允许使用
eval - 如果使用
console.log - 包含导入插件并报告非导入语句之后的任何导入
- 指示您正在使用 ES2020 语法的解析器
如果您好奇,您还可以查看create-react-app 的配置,它的内部构造真的很有趣!
Prettier
现在你已经了解了如何在项目中执行一些准则,并避免使用 ESLint 时常见的陷阱。太棒了!接下来做什么?格式化你的代码。
想象一下,你在同一个项目的三名开发人员团队中工作:
- 一位开发人员总是使用单引号而不是双引号。
- 另一个使用四个空格的缩进,使其行非常短。
- 但是,您更喜欢缩进两个空格,并且通常使用双引号。
那么,如果你需要在同一个项目上进行合作,会发生什么呢?嗯:
- 你的代码很乱。
- 浪费时间用自己的代码风格重写别人的代码
如何解决这个问题?使用通用的代码风格。怎么做?使用Prettier:一个专业的代码格式化工具。它不仅支持 JavaScript,还支持许多其他语言,例如
JSX、CSS、JSON 或 Vue。
安装 Prettier
您可以通过两种不同的方式安装 Prettier:
- 全球范围内:
npm install prettier -g - 关于一个项目:
npm install prettier --save-dev
就像 ESLint 一样,我建议您在项目中安装 Prettier 而不是全局安装,因为它可能会与其他项目冲突。
注意:您还可以使用VSCode 的 Prettier 扩展。通过从 VSCode 格式化代码,它将极大地改善您的开发人员体验。
配置 Prettier
如上所述,Prettier 是一款固执己见的代码格式化程序。它会默认以你可能不喜欢的方式格式化你的代码。但它允许你修改一些内容。你可以通过.prettierrc文件或文件prettier中的键来配置它package.json。例如,以下是一些你可以配置的规则:
singleQuote:true如果您想使用单引号,false否则。printWidth:指定打印机将换行的行长度的数字。semi:true如果您想在每个语句的末尾打印分号,false否则。
如果您想查找更多选项,请单击此处。
Prettier CLI
Prettier 与 ESLint 类似,也提供命令行界面 (CLI) 来格式化文件。你可以在Prettier 的文档中找到许多选项。你最常使用的选项是--write,它与 ESLint 的选项类似--fix。例如,以下命令将格式化文件夹中的所有.js文件:.jsxsrc
prettier --write src/*.(js|jsx)
然后,您可以使用此 CLI 选项在文件中包含格式脚本package.json:
{
"scripts": {
"format": "prettier --write \"**/*.+(js|jsx|json|css|md)\""
}
}
现在,您只需运行npm run format即可格式化整个代码库。
将 Prettier 与 ESLint 集成
Prettier 可以格式化我们的代码,但谁说 ESLint 不行呢?事实上,ESLint 也有一些格式化规则,比如max-len(类似于printWidth)或quotes。不过,如果你使用 Prettier,就不需要这些规则了。Prettier取代了ESLint 的格式化规则,但并没有取代代码质量规则。
因此,您可以通过安装以下内容将 Prettier 集成到您的 ESLint 配置中:
npm install --save-dev eslint-config-prettier eslint-plugin-prettier
eslint-config-prettier禁用与 Prettier 冲突的规则。同时eslint-plugin-prettier添加使用 Prettier 格式化内容的规则。您可以使用推荐的配置来启用此配置:
{
"extends": ["plugin:prettier/recommended"]
}
Prettier 配置示例
以下是 Prettier 配置的一个示例(.prettierrc):
{
"printWidth": 85,
"arrowParens": "always",
"semi": false,
"tabWidth": 2
}
基本上,这意味着 Prettier:
- 超过 85 个字符的行将换行。
- 即使只有一个参数,也总是在箭头函数周围使用括号。
- 不会在每个语句的末尾打印分号。
- 每个缩进级别将使用两个空格。
让我们以一个混乱但简单的 React 组件为例,并通过尝试其在线游乐场来直观地了解 Prettier 的效果:
这立刻就提高了可读性,相信我,手动格式化会浪费你的时间。所以使用格式化程序至关重要。
每次提交时进行 Lint 和格式化
你可以对代码库进行 lint 和运行,这很棒。但这是否意味着你现在应该随时对代码进行 lint 和格式化?不!
如果你在项目中使用 Git(谁会不用呢),你可以在每次提交或推送之前使用Git Hooks运行 ESLint 和 Prettier。这样,你的代码在部署到生产环境之前就会被持续地 lint 和格式化 😉
沙哑
我们这里说的不是狗,而是能让你轻松设置 Git 钩子的工具。假设你package.json有以下脚本,并且你想在每次提交时lint运行:format
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint .",
"format": "prettier --write \"**/*.+(js|jsx|json|yml|yaml|css|md|vue)\""
}
}
然后,您可以通过两个简单的步骤添加 Git hooks:
- 安装 Husky 作为开发依赖项:
npm install --save-dev husky
- 在您的中插入以下内容
package.json:
{
"husky": {
"hooks": {
"pre-commit": "npm run lint && npm run format"
}
}
}
pre-commit就这样。每次提交时,都会运行与之关联的命令。这样你的代码库就会被 lint 和格式化。
pre-commit是目前为止使用最多的 Git 钩子,但您也可以使用其他钩子,如pre-push或post-commit。
lint-staged
请耐心等待。此工具将是最后设置的。代码库越大,lint 和格式化所需的时间就越长。想象一下,你有超过 1000 个组件。你肯定不想等待 ESLint 来 lint 所有代码库,对吧?最终,只需要 lint 那些刚刚被修改过的文件。为此,你可以使用lint-staged。事实上,这个工具将确保你 lint 那些即将提交的文件,也就是那些被暂存的文件。
要安装它,您必须运行以下命令:
npm install --save-dev lint-staged
然后,您必须lint-staged向您的配置文件package.json或文件添加一个键。根据lint-staged 文档,配置应该是一个对象,其中每个值代表一个或多个要运行的命令,而其键是用于这些命令的全局模式。以下是示例:.lintstagedrc
{
"lint-staged": {
"*.+(js|jsx)": "eslint --fix",
"*.+(json|css|md)": "prettier --write"
}
}
此配置将允许您运行 ESLint 并修复.js和.jsx文件。同时,它将在.json、.css和.md文件上运行 Prettier。
使用预提交在 React 应用上设置 ESLint 和 Prettier
在本部分中,我们将了解如何在create-react-app生成的应用上设置 Prettier、husky 和 lint-staged 。更准确地说,我们将:
- 将 Prettier 的推荐配置添加到 ESLint 中,并添加以下格式规则(参见Prettier 的选项):
- 必须
printWidth设置为 90 - 对象文字中的括号之间不应有空格。
- ES5 中有效的尾部应该有逗号
- 将 husky 和 lint-staged 添加到 lint 并仅格式化暂存文件:
- 应该有一个
pre-commit运行的钩子lint-staged - 非 JavaScript 文件(CSS、JSON、HTML 等)应使用 Prettier 进行格式化
- JS 和 JSX 文件应该被 lint(并且借助 Prettier 的 ESLint 插件重新格式化)
让我们创建一个 React 应用。进入你通常工作的文件夹并运行:
npx create-react-app react-eslint-prettier-app
注意:如果您无法使用npx,则可能意味着您使用的 npm 版本过旧(低于 5.2)。要解决此问题,请更新 npm 或create-react-app使用 进行全局安装npm install -g。
首先,让我们看看如何设置 Prettier。为此,我们需要安装devDependenciesPrettier 及其插件:
npm install --save-dev prettier eslint-config-prettier eslint-plugin-prettier
提醒一下,eslint-config-prettier将禁用所有可能与 Prettier 规则冲突的 ESLint 格式规则。eslint-plugin-prettier是将添加 Prettier 格式规则的插件。
然后,让我们告诉 ESLint 我们将使用 Prettier 推荐的配置:
{
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest",
"plugin:prettier/recommended"
]
}
完成后,我们需要指定 Prettier 的选项。为此,您可以创建一个文件,或者在 中.prettierrc添加一个键。我们选择第二个选项:prettierpackage.json
{
"prettier": {
"printWidth": 90,
"bracketSpacing": false,
"trailingComma": "es5"
}
}
让我们在暂存文件上添加钩子。为此,pre-commit我们需要在 中安装husky和:lint-stageddevDependencies
npm install --save-dev husky lint-staged
pre-commit然后,我们通过添加一个husky键来添加钩子本身package.json:
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
}
如果我们保持原样,它将会失败,因为我们没有指定配置lint-staged,所以让我们立即执行此操作:
{
"lint-staged": {
"*.+(js|jsx)": ["eslint --fix", "git add"],
"*.+(json|css|md)": ["prettier --write", "git add"]
}
}
这里我们使用 ESLint 来检查和格式化 JS 和 JSX 文件。我们还使用 Prettier 来格式化json、css和markdown文件。瞧!完美设置!完整文件如下package.json:
{
"name": "react-eslint-prettier-app",
"version": "0.1.0",
"private": true,
"dependencies": {
...
},
"scripts": {
...
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest",
"plugin:prettier/recommended"
]
},
"prettier": {
"printWidth": 90,
"bracketSpacing": false,
"trailingComma": "es5"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.+(js|jsx)": "eslint --fix",
"*.+(json|css|md)": "prettier --write"
},
"browserslist": {
...
},
"devDependencies": {
"eslint-config-prettier": "^7.2.0",
"eslint-plugin-prettier": "^3.3.1",
"husky": "^4.3.8",
"lint-staged": "^10.5.3",
"prettier": "^2.2.1"
}
}
如果一切顺利,您应该会有一个pre-commit既可以检查代码又可以格式化代码的钩子。
