Skip to content

Commit baa3aee

Browse files
committed
完成 TypeScript 与 ESLint 一章
1 parent 80a6cb5 commit baa3aee

File tree

5 files changed

+234
-26
lines changed

5 files changed

+234
-26
lines changed

.eslintrc.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ module.exports = {
44
'typescript'
55
],
66
rules: {
7-
'spaced-comment': 'off',
8-
// 'react/no-unescaped-entities': 'off',
9-
// 'react/self-closing-comp': 'off',
10-
// 'react/void-dom-elements-no-children': 'off',
11-
'react/jsx-indent': 'off',
12-
// 'react/jsx-indent-props': 'off',
13-
// 'react/jsx-max-props-per-line': 'off'
14-
// 还不支持 properties https://github.com/yannickcr/eslint-plugin-react/issues/1342
15-
'react/sort-comp': 'off',
16-
'typescript/no-unused-vars': 'error'
7+
// @fixable 必须使用 === 或 !==,禁止使用 == 或 !=,与 null 比较时除外
8+
'eqeqeq': [
9+
'error',
10+
'always',
11+
{
12+
null: 'ignore'
13+
}
14+
],
15+
// 类和接口的命名必须遵守帕斯卡命名法,比如 PersianCat
16+
'typescript/class-name-casing': 'error'
1717
}
18-
};
18+
}

assets/vscode-eslint-error.png

24.5 KB
Loading

assets/vscode-output-eslint.png

11.6 KB
Loading

ecosystem/eslint.md

Lines changed: 215 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# TypeScript 与 ESLint(草稿)
1+
# TypeScript 与 ESLint
22

33
[ESLint][] 是一个代码检查工具,主要用来发现代码错误、统一代码风格,目前已被广泛的应用于各种 JavaScript 项目中。
44

@@ -29,7 +29,7 @@ console.log(`My name is ${myName}`)
2929
//
3030
// eslint 报错信息:
3131
//
32-
// index.ts
32+
// /path/to/index.ts
3333
// 3:27 error 'myNane' is not defined no-undef
3434
// 5:38 error Missing semicolon semi
3535
//
@@ -55,7 +55,7 @@ console.log(`My name is ${myName}`)
5555

5656
上图中,TypeScript 与 ESLint 有重叠的部分,也有各自独立的部分,虽然发现代码错误比统一的代码风格更重要,但是当一个项目越来越庞大,开发人员也越来越多的时候,代码风格的约束还是必不可少的。
5757

58-
下面我们就来一步一步给我们的 TypeScript 项目添加 ESLint 检查。
58+
下面我们就来一步一步给 TypeScript 项目添加 ESLint 检查。
5959

6060
## 安装
6161

@@ -65,10 +65,10 @@ ESLint 可以安装在当前项目中或全局环境下,因为代码检查是
6565
npm install eslint --save-dev
6666
```
6767

68-
由于 ESLint 默认使用 [Espree](https://github.com/eslint/espree) 进行语法解析,无法识别 TypeScript 的一些语法,故我们需要安装 `typescript-eslint-parser`,替代掉默认的解析器:
68+
由于 ESLint 默认使用 [Espree](https://github.com/eslint/espree) 进行语法解析,无法识别 TypeScript 的一些语法,故我们需要安装 `typescript-eslint-parser`,替代掉默认的解析器,别忘了同时安装 `typescript`
6969

7070
```bash
71-
npm install typescript-eslint-parser --save-dev
71+
npm install typescript typescript-eslint-parser --save-dev
7272
```
7373

7474
由于 `typescript-eslint-parser` 对一部分 ESLint 规则支持性不好,故我们需要安装 `eslint-plugin-typescript`,弥补一些支持性不好的规则。
@@ -86,25 +86,227 @@ ESLint 需要一个配置文件来决定对哪些规则进行检查,配置文
8686
我们在项目的根目录下创建一个 `.eslintrc.js`,内容如下:
8787

8888
```js
89+
module.exports = {
90+
parser: 'typescript-eslint-parser',
91+
plugins: [
92+
'typescript'
93+
],
94+
rules: {
95+
// @fixable 必须使用 === 或 !==,禁止使用 == 或 !=,与 null 比较时除外
96+
'eqeqeq': [
97+
'error',
98+
'always',
99+
{
100+
null: 'ignore'
101+
}
102+
],
103+
// 类和接口的命名必须遵守帕斯卡命名法,比如 PersianCat
104+
'typescript/class-name-casing': 'error'
105+
}
106+
}
107+
```
108+
109+
以上配置中,我们指定了两个规则,其中 `eqeqeq` 是 ESLint 原生的规则(它要求必须使用 `===``!==`,禁止使用 `==``!=`,与 `null` 比较时除外),`typescript/class-name-casing``eslint-plugin-typescript` 为 ESLint 增加的规则(它要求类和接口的命名必须遵守帕斯卡命名法,比如 `PersianCat`)。
110+
111+
规则的取值一般是一个数组(上例中的 `eqeqeq`),其中第一项是 `off``warn``error` 中的一个,表示关闭、警告和报错。后面的项都是该规则的其他配置。
112+
113+
如果没有其他配置的话,则可以将规则的取值简写为数组中的第一项(上例中的 `typescirpt/class-name-casing`)。
114+
115+
关闭、警告和报错的含义如下:
116+
117+
- 关闭:禁用此规则
118+
- 警告:代码检查时输出错误信息,但是不会影响到 exit code
119+
- 报错:发现错误时,不仅会输出错误信息,而且 exit code 将被设为 1(一般 exit code 不为 0 则表示执行出现错误)
120+
121+
## 检查一个 ts 文件
122+
123+
创建了配置文件之后,我们来创建一个 ts 文件看看是否能用 ESLint 去检查它了。
124+
125+
创建一个新文件 `index.ts`,将以下内容复制进去:
126+
127+
```ts
128+
interface person {
129+
name: string;
130+
age: number;
131+
}
132+
133+
let tom: person = {
134+
name: 'Tom',
135+
age: 25
136+
};
137+
138+
if (tom.age == 25) {
139+
console.log(tom.name + 'is 25 years old.');
140+
}
141+
```
142+
143+
然后执行以下命令:
144+
145+
```bash
146+
./node_modules/.bin/eslint index.ts
147+
```
148+
149+
则会得到如下报错信息:
150+
151+
```bash
152+
/path/to/index.ts
153+
1:11 error Interface 'person' must be PascalCased typescript/class-name-casing
154+
11:13 error Expected '===' and instead saw '==' eqeqeq
155+
156+
✖ 2 problems (2 errors, 0 warnings)
157+
```
158+
159+
上面的结果显示,刚刚配置的两个规则都生效了:接口 `person` 必须写成帕斯卡命名规范,`==` 必须写成 `===`
160+
161+
需要注意的是,我们使用的是 `./node_modules/.bin/eslint`,而不是全局的 `eslint` 脚本,这是因为代码检查是项目的重要组成部分,所以我们一般会将它安装在当前项目中。
162+
163+
可是每次执行这么长一段脚本颇有不便,我们可以在 `package.json` 中添加一个 `script` 来简化这个步骤:
164+
165+
```json
166+
{
167+
"scripts": {
168+
"eslint": "eslint index.ts"
169+
}
170+
}
171+
```
172+
173+
这时只需执行 `npm run eslint` 即可。
174+
175+
## 检查整个项目的 ts 文件
176+
177+
我们的项目源文件一般是放在 `src` 目录下,所以需要将 `package.json` 中的 `eslint` 脚本改为对一个目录进行检查。由于 `eslint` 默认不会检查 `.ts` 后缀的文件,所以需要加上参数 `--ext .ts`
178+
179+
```json
180+
{
181+
"scripts": {
182+
"eslint": "eslint src --ext .ts"
183+
}
184+
}
185+
```
89186

187+
此时执行 `npm run eslint` 即会检查 `src` 目录下的所有 `.ts` 后缀的文件。
188+
189+
## 在 VSCode 中集成 ESLint 检查
190+
191+
在编辑器中集成 ESLint 检查,可以在开发过程中就发现错误,极大的增加了开发效率。
192+
193+
要在 VSCode 中集成 ESLint 检查,我们需要先安装 ESLint 插件,点击「扩展」按钮,搜索 ESLint,然后安装即可。
194+
195+
VSCode 中的 ESLint 插件默认是不会检查 `.ts` 后缀的,需要在「文件 => 首选项 => 设置」中,添加以下配置:
196+
197+
```json
198+
{
199+
"eslint.validate": [
200+
"javascript",
201+
"javascriptreact",
202+
"typescript"
203+
]
204+
}
205+
```
206+
207+
这时再打开一个 `.ts` 文件,将鼠标移到红色提示处,即可看到这样的报错信息了:
208+
209+
![VSCode ESLint 错误信息](../assets/vscode-eslint-error.png)
210+
211+
## 使用已完善的配置
212+
213+
ESLint 原生的规则和 `eslint-plugin-typescript` 的规则太多了,而且原生的规则有一些在 TypeScript 中支持的不好,需要禁用掉。
214+
215+
这里我推荐使用 [AlloyTeam ESLint 规则中的 TypeScript 版本](https://github.com/AlloyTeam/eslint-config-alloy#typescript),它已经为我们提供了一套完善的配置规则。
216+
217+
安装:
218+
219+
```bash
220+
npm install --save-dev eslint typescript typescript-eslint-parser eslint-plugin-typescript eslint-config-alloy
90221
```
91222

92-
- 使用 ESLint 加上
223+
在你的项目根目录下创建 `.eslintrc.js`,并将以下内容复制到文件中:
224+
225+
```js
226+
module.exports = {
227+
extends: [
228+
'eslint-config-alloy/typescript',
229+
],
230+
globals: {
231+
// 这里填入你的项目需要的全局变量
232+
// 这里值为 false 表示这个全局变量不允许被重新赋值,比如:
233+
//
234+
// jQuery: false,
235+
// $: false
236+
},
237+
rules: {
238+
// 这里填入你的项目需要的个性化配置,比如:
239+
//
240+
// // @fixable 一个缩进必须用两个空格替代
241+
// 'indent': [
242+
// 'error',
243+
// 2,
244+
// {
245+
// SwitchCase: 1,
246+
// flatTernaryExpressions: true
247+
// }
248+
// ]
249+
}
250+
};
251+
```
252+
253+
## 使用 ESLint 检查 tsx 文件
254+
255+
如果需要同时支持对 tsx 文件的检查,则需要对以上步骤做一些调整:
256+
257+
### 安装 `eslint-plugin-react`
258+
259+
```bash
260+
npm install --save-dev eslint-plugin-react
261+
```
262+
263+
### package.json 中的 scripts.eslint 添加 `.tsx` 后缀
264+
265+
```json
266+
{
267+
"scripts": {
268+
"eslint": "eslint src --ext .ts,.tsx"
269+
}
270+
}
271+
```
272+
273+
### VSCode 的配置中新增 typescriptreact 检查
274+
275+
```json
276+
{
277+
"eslint.validate": [
278+
"javascript",
279+
"javascriptreact",
280+
"typescript",
281+
"typescriptreact"
282+
]
283+
}
284+
```
285+
286+
### 使用 AlloyTeam ESLint 规则中的 TypeScript React 版本
287+
288+
[AlloyTeam ESLint 规则中的 TypeScript React 版本](https://github.com/AlloyTeam/eslint-config-alloy#typescript-react)
289+
290+
## Troubleshootings
93291

94-
运行 eslint 时报错 Cannot find module 'typescript-eslint-parser'
292+
### Cannot find module 'typescript-eslint-parser'
95293

96-
你运行的是全局的 eslint,需要运行 `./node_modules/.bin/eslint xxx.ts'
294+
你运行的是全局的 eslint,需要改为运行 `./node_modules/.bin/eslint`
97295

98-
不支持某些 规则,比如 no-undef
296+
### cannot read property type of null
99297

100-
有冲突的规则,比如 spaced-comment
298+
需要关闭 `eslint-plugin-react` 中的规则 `react/jsx-indent`
101299

300+
### VSCode 没有显示出 ESLint 的报错
102301

103-
cannot read property type of null
104-
react 规则不可用
302+
1. 检查「文件 => 首选项 => 设置」中有没有配置正确
303+
2. 检查必要的 npm 包有没有安装
304+
3. 检查 `.eslintrc.js` 有没有配置
305+
4. 检查文件是不是在 `.eslintignore`
105306

307+
如果以上步骤都不奏效,则可以在「文件 => 首选项 => 设置」中配置 `"eslint.trace.server": "messages"`,按 `Ctrl`+`Shift`+`U` 打开输出面板,然后选择 ESLint 输出,查看具体错误。
106308

107-
react/sort-comp type-annotations
309+
![VSCode 的 ESLint 输出](../assets/vscode-output-eslint.png)
108310

109311
[ESLint]: https://eslint.org/
110312
[`typescript-eslint-parser`]: https://github.com/eslint/typescript-eslint-parser

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"example": "examples"
88
},
99
"scripts": {
10-
"test": "echo \"Error: no test specified\" && exit 1"
10+
"eslint": "eslint index.ts"
1111
},
1212
"repository": {
1313
"type": "git",
@@ -23,5 +23,11 @@
2323
"bugs": {
2424
"url": "https://github.com/xcatliu/typescript-tutorial/issues"
2525
},
26-
"homepage": "https://github.com/xcatliu/typescript-tutorial#readme"
26+
"homepage": "https://github.com/xcatliu/typescript-tutorial#readme",
27+
"devDependencies": {
28+
"eslint": "^4.11.0",
29+
"eslint-plugin-typescript": "^0.8.0",
30+
"typescript": "^2.6.1",
31+
"typescript-eslint-parser": "^9.0.0"
32+
}
2733
}

0 commit comments

Comments
 (0)