背景
我们的一些项目中用到了 TSLint 来规范我们的 TypeScript 代码,甚至没有 Lint 工具来辅助开发,我们这里希望用 ESLint 来取代 TSLint,主要原因是 TSLint 已经被官方放弃,所以我们采用 ESLint,并结合 prettier 来规范我们的代码和统一团队风格。
一、安装 ESLint,删除 TSLint
由于我们的项目可能不大一样,有的项目是没有任何 lint 工具,有的是 vue-cli 自带安装的 ESLint 或者 TSLint,这里大家参考 package.json 文件,自行选择。我现在以我手头上的 shopintar 项目为例,仅有 TSLint。
-
1、首先删除 tslint.json 配置文件
-
2、安装相关依赖
npm i -d eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin @typescript-eslint/parser: ESLint 专门解析 TypeScript 的解析器
@typescript-eslint/eslint-plugin: 内置各种解析 TypeScript rules 插件 -
3、新建 .eslintrc.js 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | module.exports = { root: true, env: { browser: true, node: true, es6: true, }, parser: 'vue-eslint-parser', extends: [ 'plugin:vue/recommended', 'plugin:prettier/recommended', 'prettier/@typescript-eslint', 'plugin:@typescript-eslint/recommended', ], plugins: ['vue', '@typescript-eslint'], parserOptions: { parser: '@typescript-eslint/parser', sourceType: 'module', ecmaVersion: 2018, }, rules: { 'prettier/prettier': 'error', 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 'space-before-function-paren': [2, 'never'], // function 的圆括号之前是否使用空格 'array-bracket-spacing': 2, 'no-var': 2, 'no-eval': 2, 'arrow-spacing': 2, 'block-spacing': 2, 'key-spacing': 2, 'brace-style': 2, camelcase: 2, 'comma-dangle': [2, 'always-multiline'], eqeqeq: [2, 'always', { null: 'ignore' }], 'object-curly-spacing': [2, 'always'], 'nonblock-statement-body-position': 2, // if 语句后必须跟大括号 // 设置typescript-eslint规则 // https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin/docs/rules '@typescript-eslint/member-delimiter-style': [ 2, { multiline: { delimiter: 'none', // 'none' or 'semi' or 'comma' requireLast: true, }, singleline: { delimiter: 'semi', // 'semi' or 'comma' requireLast: false, }, }, ], '@typescript-eslint/interface-name-prefix': [2, { prefixWithI: 'always' }], '@typescript-eslint/explicit-function-return-type': ['off'], '@typescript-eslint/no-explicit-any': ["off"] // 先忽略,但是尽量少用 any }, } |
注意: parser: 'vue-eslint-parser',这里要区分和 parserOptions.parser 的区别,vue-eslint-parser 是解析 .vue 文件,而 parserOptions.parser:@typescript-eslint/parser 是我们自定义来解析 TypeScript 的,否则就无法正确的检验 TypeScript。相关解释
二、安装 prettier
prettier 用来做格式化工具配合我们的 ESLint 可以更大的发挥作用,首先安装相关依赖:
eslint-config-prettier: 这个插件的作用是当 ESLint 和 prettier 配置冲突时优先 prettier
eslint-plugin-prettier: 将 prettier 作为 ESLint 规范来使用
接着按需配置 prettier,新建 .prettierrc 文件
1 2 3 4 5 6 7 8 | { "singleQuote": true, "tabWidth": 2, "useTabs": false, "semi": false, "trailingComma": "all", "printWidth": 120 } |
然后在 .eslintrc.js 文件中引入 prettier 配置,在 extends 数组中添加 prettier/@typescript-eslint 和 plugin:prettier/recommended,到这里 ESLint 和 prettier 相关配置已经完成,接下来我们利用一些工具帮我们在 git commit 阶段完成代码格式化和校验工作。
三、使用 husky & lint-staged 自动完成校验与格式化
- husky 是控制代码提交的钩子,在代码被提交到Git仓库之前,我们可以在这里做一些预检查或者格式化工作。
- lint-staged是一个前端文件过滤的工具(仅仅是文件过滤器),可以对文件系统进行过滤,使得每次提交不必对所有文件进行校验
1. 安装husky 和 lint-staged
1 | npm install husky lint-staged -D |
2. 修改 package.json,增加配置:
1 2 3 4 5 6 7 8 9 10 | "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "src/**/*.{ts,vue}": [ "eslint --fix", "git add" ] } |
上面配置,每次它只会在你本地 commit 之前,校验你提交的内容是否符合你本地配置的 eslint规则,如果符合规则,则会提交成功。如果不符合它会自动执行 eslint —fix 尝试帮你自动修复,如果修复成功则会帮你把修复好的代码提交,如果失败,则会提示你错误,让你修好这个错误之后才能允许你提交代码。
拓展: 除了在package.json中配置,也可以在.lintstagedrc、lint-staged.config.js 文件中,lint-staged 的常用选项除了liners 之外,还有
ignore 、concurrent 等,具体参考文档:
1 2 3 4 5 6 7 8 | { "lint-staged": { "linters": { "*.{js,scss}": ["some command", "git add"] }, "ignore": ["**/dist/*.min.js"] } } |
二、使用 Commitlint
Commitlint 可以对代码提交的信息进行规范和校验,方便 团队协作和快速定位问题
1. 安装
1 2 3 4 | npm install --save-dev @commitlint/config-conventional @commitlint/cli // 生成配置文件commitlint.config.js,当然也可以是 .commitlintrc.js echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js |
2. 配置
在husky的配置加入CommitlIint配置,”commit-msg": "commitlint -e $HUSKY_GIT_PARAMS”
1 2 3 4 5 6 | husky: { hooks: { "pre-commit": "lint-staged", "commit-msg": "commitlint -e $HUSKY_GIT_PARAMS" } }, |
3. 定制提交规范
- build: 影响构建系统或外部依赖关系的更改(示例范围:gulp、broccoli、npm)
- ci: 对ci配置文件和脚本的更改(示例范围:Circle、BrowserStack、SauceLabs)
- docs: 仅文档更改
- feat: 新功能(feature)
- fix: 修补bug
- perf: 提高性能的代码更改
- refactor: 重构(既不修复错误也不添加功能的代码更改)
- style: 样式修改,不影响代码含义的更改
- test: 增加测试
例如:
1 2 | git commit -m 'feat: 增加 xxx 功能' git commit -m 'fix: 修复 xxx 功能' |
Subject
Subject是 commit 目的的简短描述,可以做一些配置,如最大长度限制。
commitlint.config.js文件配置
rule配置说明 : rule由name和配置数组组成,如:’name:[0, ‘always’, 72]’,数组中第一位为level,可选0,1,2,0为disable,1为warning,2为error,第二位为应用与否,可选always|never,第三位该rule的值。具体配置例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | module.exports = { extends: [ '@commitlint/config-conventional', ], rules: { 'type-enum': [2, 'always', [ 'build', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'style', 'revert', ]], 'type-case': [0], 'type-empty': [0], 'scope-empty': [0], 'scope-case': [0], 'subject-full-stop': [0, 'never'], 'subject-case': [0, 'never'], 'header-max-length': [0, 'always', 72], }, } |
总结
通过以上几步我们可以在 commit 之前自动帮我们完成格式化和校验的工作,但是值得注意的是,这里的格式化和校验并不是全局的,而是我们当前提交的内容,如果我们想要格式化全局代码或者校验全局代码,这里我们可以在 package.json 中的 script 命令中写个脚本需要的时候手动执行一下,而不是把它放在 pre-commit 钩子上每次 commit 都执行,耗费时间。
1 2 3 | "format": "prettier --write "src/**/*.ts" "src/**/*.vue"", "lint": "eslint --fix "src/**/*.ts" "src/**/*.vue"" |