VS Code下Eslint+Prettier+TypeScript一步到位(规范配置)

9,164 阅读6分钟

需求简述

为什么要结合使用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"
}