需求简述
为什么要结合使用eslint和prettier?因为eslint只检查代码书写,保证代码书写风格的统一规范。prettier保证代码格式上的规范整洁,例如如何换行,如何缩进等等。因此一个合格的项目eslint+prettier的配置是必不可少的。
为什么要用TypeScript就不用多说了,现在还有不用ts的前端项目吗?
因此目标为:
-
eslint+prettier+typescript完美支持
-
不管是谁的电脑,什么样的环境,项目lint都能无bug运行(重要!)
保证团队中所有成员只要用的是vscode环境都能无bug执行lint操作,包括使用的typescript版本也是一致的。(这点尤有重要,配置eslint不难,但是遇到一些我电脑可以你电脑怎么就不行的问题是最头疼的)。
前置条件
安装vscode,以及安装eslint插件。
为啥需要eslint插件呢? 因为我们需要eslint实时的去检测我们的代码,对不符合规范的代码给出提醒。这个功能是插件提供的。插件会在我们项目启动的时候起一个后台任务,读取项目本地的eslint配置,并且执行后续的lint操作。 不需要安装prettier? 可以安装。只是没有必要。如果你的项目中只包含ts和js文件不包含其他类型文件,那么你可以不安装prettier。因为我们的方案中会将prettier已插件的形式引入到eslint的配置文件中,需要prettier的能力的地方eslint自然会帮我们去调用,不需要prettier在后台另起一个服务。
配置eslint
安装依赖
pnpm install eslint eslint-plugin-import eslint-config-airbnb-base -D
eslint-plugin-import是peer-dependencies,需要引入。
airbnb的eslint规则是主流的eslint规则集合。其中它提供了针对不同技术栈的不同包。为什么不用eslint-config-airbnb或者是eslint-config-airbnb-typescript包是因为它包含有react相关的配置,我不需要,所以只需要引入eslint-config-airbnb-base即可。
新增配置文件
.eslintrc.js
module.exports = {
extends: ['eslint-config-airbnb-base']
}
.eslintignore
/node_modules
/dist
增加lint快捷命令
在package.json文件后新增script。
{
"scripts": {
"lint": "eslint 'src/**/*.{js,ts}' --fix"
}
}
文件后缀自己按需加。
配置typescript
vscode默认就支持ts,不需要引入插件或者是typescript依赖。但是我推荐引入typescript依赖。原因是ts的每个小版本之间能力都会有不少的差距。团队中每个人vscode的版本没有办法保持一致。自然ts的版本也无法保证一致。我们接着向下👇看方案。
安装依赖
pnpm install typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser -D
tslint已经不维护了,不要使用别的,就用@typescript-eslint/eslint-plugin就对了,官方推荐!作用当然是针对ts制定了一系列的eslint规则。
@typescript-eslint/parser的作用是用来解析ts语句。eslint本身不支持ts语法。
增加配置
在项目根目录新增.vscode文件夹,在下新增settings.json文件。
{
"typescript.tsdk": "./node_modules/typescript/lib",
}
新增这行配置。意义是项目中vscode使用的ts的sdk路径是我们依赖中的ts,不是vscode内置的ts版本!保证团队使用的都是同一个ts sdk。
新增tsconfig.json
{
"compilerOptions": {
"target": "es2015",
"module": "ES2015",
"lib": ["esnext", "dom"],
"strict": true,
"experimentalDecorators": true,
"sourceMap": true,
"moduleResolution": "node",
"forceConsistentCasingInFileNames": true,
"noUnusedLocals": true,
"esModuleInterop": true,
"noFallthroughCasesInSwitch": true,
"noUnusedParameters": true,
"noEmit": true,
"skipLibCheck": true,
"rootDir": "src",
"baseUrl": ".",
"allowJs": true
},
"include": ["src"],
"exclude": ["node_modules"],
}
这里仅仅给出我推荐的配置项,大多数你需要别的配置项可以自行查询官网配置。
修改.eslintrc.js
module.exports = {
extends: ['eslint-config-airbnb-base', 'plugin:@typescript-eslint/recommended'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
rules: {
'import/extensions': 'off',
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': ['error', { ignoreTypeReferences: true }],
'import/prefer-default-export': 'off',
},
settings: {
'import/resolver': {
node: {
extensions: ['.js', '.ts'],
moduleDirectory: ['node_modules', './src'],
},
},
},
parserOptions: {
project: './tsconfig.json',
},
}
可以发现rules一下子多了好多。简单讲讲为什么、解决了什么问题吧。
- 不想要在import其他module时写文件后缀,因此关掉import/extensions规则。
- typescript中的interface以及type不存在变量提升的问题,因此针对它们特别的加了两行规则,保证eslint见到interface或者type在声明前使用时不会抱怨。
- 如果单文件中只有一个导出项,则eslint会告诉你使用export default的方式导出。如果你的项目将要作为npm工具库或者是UI库,那我劝你不要使用export default,因此关掉此规则。至于原因自行搜索吧,坑比较大说不完。
ts-node支持
如果我们的项目是一个工具库,那我们很可能需要ts-node帮我们方便的执行typescript脚本文件。在这里补充了一下,需要的人自取就可以了。
安装依赖
pnpm install ts-node -D
ts-node执行脚本
package.json文件中的script中添加如下的配置项
{
"scripts": {
"test": "npx ts-node --project ./tsconfig.json ./src/filename.ts",
},
}
由于node不支持esmodule(需要一定的条件),因此需要在tsconfig.json文件中新增如下配置项
{
"ts-node": {
"transpileOnly": true,
"compilerOptions": {
"module": "commonjs"
}
}
}
配置prettier
安装依赖
pnpm install prettier eslint-plugin-prettier eslint-config-prettier -D
prettier作为peer-dependencies引入。eslint-config-prettier用来关闭所有和prettier冲突的eslint规则(prettier的规则时没有办法关闭的,很霸道!)。eslint-plugin-prettier告诉eslint应该怎么按照prettier的方式去格式化文档。
增加配置
新增.prettierrc文件
{
"semi": false,
"tabWidth": 2,
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 140
}
可以配置的不多,自己看着来。
修改.eslintrc.js
module.exports = {
extends: ['eslint-config-airbnb-base', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
rules: {
'import/extensions': 'off',
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': ['error', { ignoreTypeReferences: true }],
'no-prototype-builtins': 'off',
'import/prefer-default-export': 'off',
},
settings: {
'import/resolver': {
node: {
extensions: ['.js', '.ts'],
moduleDirectory: ['node_modules', './src'],
},
},
},
parserOptions: {
project: './tsconfig.json',
},
}
保证 plugin:prettier/recommended放在最后。
修改settings.json(重要)
项目需要保存时自动执行lint操作。如果是非js或者是ts文件我们通常还是需要prettier帮我们进行代码风格的格式化。因此我们还是需要安装prettier插件,并且设置保存时使用prettier来格式化。因此有了下面的配置项。
{
"typescript.tsdk": "./node_modules/typescript/lib",
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
指定默认格式化工具很重要。即使你的eslint以及其他配置项都对,但是保存的时候代码闪来闪去那说明你的默认格式化工具不正确。
最后
前端环境配置是个比较头疼的问题。仅仅是eslint配置的内容也很复杂。不只是新增几个包然后extends以及关掉几个rules那么简单。需要了解vscode的配置、指定格式化工具、如何和prettier不打架、以及如何支持ts,react等等吧。能一劳永逸是最好的,希望你们少踩坑。
最后还有一点很重要很重要。那就是版本问题。各个plugin和eslint的版本不匹配eslint也会哭给你看!这个坑我已经踩过了。我现在的依赖版本是最新的也是没有问题的版本,我放下面了。
{
"@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/parser": "^5.3.0",
"eslint": "^8.1.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-prettier": "^4.0.0",
"prettier": "^2.4.1"
}