目的
工程配置主要是为了能够在团队开发中统一代码规范,避免因为代码风格不统一或其它不一致的问题导致的整合冲突
- 编辑器风格(EditorConfig、prettier)
- 代码规范和校验(eslint、stylint)
- git提交规范(commitlint)
参考文章:我是这样搭建Typescript+React项目环境的
vscode 必备插件
package.json
初始化package.json
:
npm init -y
.gitignore
ctrl+shift+p 召唤命令面板,输入 Add gitignore 命令,新建 .gitignore
或者直接新建:
touch .gitignore
.npmrc
统一npm
依赖源
# 创建 .npmrc 文件
touch .npmrc
# 在该文件内输入配置
registry=https://registry.npm.taobao.org/
因为项目中会用到react
和typescript
,所以先装上这两个依赖包:
npm install typescript -D
npm install react react-dom -S
README.md
新建 README
文件
touch README.md
EditorConfig
.editorconfig
是跨编辑器维护一致编码风格的配置文件
vscode
安装插件EditorConfig
,根目录新建文件.editorconfig
:
touch .editorconfig
输入以下配置:
root = true
[*]
indent_style = tab
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
[*.md]
trim_trailing_whitespace = false
indent_style
缩进风格,可选配置有 tab 和 spaceindent_size
缩进大小charset
编码格式trim_trailing_whitespace
去除多余的空格insert_final_newline
在尾部插入一行end_of_line
换行符
更多配置可以查看EditorConfig
Prettier
Prettier
统一项目风格
prettier 依赖包
npm install prettier -D
根目录新建文件.prettierrc
:
touch .prettierrc
输入以下配置:
{
"trailingComma": "none",
"tabWidth": 2,
"semi": true,
"endOfLine": "lf",
"printWidth": 120,
"bracketSpacing": true,
"arrowParens": "always"
}
trailingComma
对象的最后一个属性末尾添加,
tabWidth
缩进大小semi
末尾是否添加分号singleQuote
是否单引号jsxSingleQuote
jsx 语法是否单引号endOfLine
与 .editorconfig 保持一致设置printWidth
单行代码最长字符长度,超过之后会自动格式化换行bracketSpacing
花括号里面有空格{a:1}
=>{ a: 1}
arrowParens
箭头函数的参数括号包裹(a)=>{}
更多配置请查看Prettier Playground
prettier 插件
vscode 安装扩展 Prettier - Code formatter
根目录下新建文件夹.vscode
,再此文件夹下新建settings.json
:
mkdir .vscode
touch .vscode/settings.json
该文件的配置优先于 vscode 全局的settings.json
,不过要在工作区workspace
的根目录下才会生效。
settings.json
配置:
{
// 指定哪些文件不参与搜索
"search.exclude": {
"**/node_modules": true,
"dist": true,
"build": true,
"yarn.lock": true,
"package-lock.json": true
},
"editor.formatOnSave": true,
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
ESLint
安装 eslint
npm install eslint -D
安装成功后,执行以下命令:
npx eslint --init
//termail
1、How would you like to use ESLint?
= To check syntax, find problems, and enforce code style
2、What type of modules does your project use?
= JavaScript modules (import/export)
3、Which framework does your project use?
= React
4、Does your project use TypeScript?
= Typescript
5、Where does your code run?
= Browser & Node
6、How would you like to define a style for your project?
= Use a popular style guide
7、Which style guide do you want to follow?
= Airbnb
8、What format do you want your config file to be in?
= JavaScript
9、Would you like to install them now with npm?
= Yes
对生成的.eslintrc.js
文件,还要做以下修改:
- 根据 eslint-config-airbnb 官方说明,如果要开启 React Hooks 的检查,需要在 extends 中添加一项
'airbnb/hooks'
。 - 根据 @typescript-eslint/eslint-plugin 官方说明,在 extends 中添加
'plugin:@typescript-eslint/recommended'
可开启针对 ts 语法推荐的规则定义。 - 需要添加一条很重要的
rule
,不然在typescript
中通过import
导入会报错
添加以下规则到 rules
:
rules: {
'import/extensions': [
ERROR,
'ignorePackages',
{
ts: 'never',
tsx: 'never',
json: 'never',
js: 'never',
},
],
}
添加settings
配置:
settings: {
'import/resolver': {
node: {
extensions: ['.tsx', '.ts', '.js', '.json'],
},
},
},
ESLint 和 Prettier 的冲突
配置完会发现,vscode
一直在标红,因为eslint
的配置规则跟prettier
冲突了
安装 eslint-config-prettier
:
npm install eslint-config-prettier -D
添加以下配置到 .eslintrc.js
的 extends
中:
{
extends: [
// other configs ...
'prettier',
'prettier/@typescript-eslint',
'prettier/react',
'prettier/unicorn',
]
}
eslint 扩展插件
eslint-plugin-promise
让你把 Promise 语法写成最佳实践eslint-plugin-unicorn
提供了更多有用的配置项
npm install eslint-plugin-promise eslint-plugin-unicorn -D
修改.eslintrc.js
文件如下:
const OFF = 0;
const WARN = 1;
const ERROR = 2;
module.exports = {
env: {
browser: true,
es2020: true,
node: true
},
extends: [
'airbnb',
'airbnb/hooks',
'plugin:react/recommended',
'plugin:unicorn/recommended',
'plugin:promise/recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'prettier/@typescript-eslint',
'prettier/react',
'prettier/unicorn'
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true
},
ecmaVersion: 11,
sourceType: 'module'
},
plugins: ['react', 'unicorn', 'promise', '@typescript-eslint'],
settings: {
'import/resolver': {
node: {
extensions: ['.tsx', '.ts', '.js', '.json']
},
typescript: {}
}
},
rules: {
'import/extensions': [
ERROR,
'ignorePackages',
{
ts: 'never',
tsx: 'never',
js: 'never'
}
],
'import/no-extraneous-dependencies': [ERROR, { devDependencies: true }],
'import/prefer-default-export': OFF,
'import/no-unresolved': ERROR,
'unicorn/better-regex': ERROR,
'unicorn/prevent-abbreviations': OFF,
'unicorn/filename-case': [
ERROR,
{
cases: {
// 中划线
kebabCase: true,
// 小驼峰
camelCase: true,
// 下划线
snakeCase: false,
// 大驼峰
pascalCase: true
}
}
],
'unicorn/no-array-instanceof': WARN,
'unicorn/no-for-loop': WARN, // 使用 for of 和 .entries 代替传统的 for 循环
'unicorn/prefer-add-event-listener': [
ERROR,
{
excludedPackages: ['koa', 'sax']
}
],
'unicorn/prefer-query-selector': ERROR,
'unicorn/no-null': OFF,
'unicorn/import-style': OFF,
'@typescript-eslint/no-useless-constructor': ERROR,
'@typescript-eslint/no-empty-function': WARN,
'@typescript-eslint/no-var-requires': OFF,
'@typescript-eslint/explicit-function-return-type': OFF,
'@typescript-eslint/explicit-module-boundary-types': OFF,
'@typescript-eslint/no-explicit-any': OFF,
'@typescript-eslint/no-unused-vars': [OFF],
'react/jsx-filename-extension': [ERROR, { extensions: ['.tsx', 'ts', '.jsx', 'js'] }],
'react/jsx-indent-props': [ERROR, 'tab'],
'react/jsx-indent': [ERROR, 'tab'],
'react/jsx-one-expression-per-line': OFF,
'react/destructuring-assignment': OFF,
'react/state-in-constructor': OFF,
'react/jsx-props-no-spreading': OFF,
'react/prefer-stateless-function': OFF,
'jsx-a11y/click-events-have-key-events': OFF,
'jsx-a11y/no-noninteractive-element-interactions': OFF,
'lines-between-class-members': [ERROR, 'always'],
indent: [ERROR, 'tab', { SwitchCase: 1 }],
'linebreak-style': [ERROR, 'unix'],
semi: [ERROR, 'always'],
'no-unused-expressions': WARN,
'no-plusplus': OFF,
'no-console': OFF,
'no-unused-vars': OFF,
'no-use-before-define': OFF,
'class-methods-use-this': ERROR,
'global-require': OFF
}
};
eslint vscode 配置
ESLint 插件可以提供编辑器自动修复功能
安装完成添加配置到 .vscode/settings.json
:
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
"typescript.tsdk": "./node_modules/typescript/lib", // 代替 vscode 的 ts 语法智能提示
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
},
.eslintignore 和 .prettierignore
新建 .eslintignore
和 .prettierignore
:
touch .eslintignore .prettierignore
输入以下内容:
/node_modules
/build
/dist
StyleLint
接下来统一样式风格,安装两个的依赖包包:
npm install stylelint stylelint-config-standard -D
项目根目录新建 .stylelintrc.js
文件:
touch .stylelintrc.js
输入以下内容:
module.exports = {
extends: ['stylelint-config-standard'],
rules: {
'comment-empty-line-before': null,
'declaration-empty-line-before': null,
'function-name-case': 'lower',
'no-descending-specificity': null,
'no-invalid-double-slash-comments': null,
'rule-empty-line-before': 'always',
},
ignoreFiles: ['node_modules/**/*', 'build/**/*'],
}
extends
预设规则扩展rules
具体的规则ignoreFiles
忽略配置字段
vscode
同步配套插件 stylelint
.vscode/settings.json
中新增以下代码:
{
// 使用 stylelint 自身的校验即可
"css.validate": false,
"less.validate": false,
"scss.validate": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
},
}
stylelint extends 和 stylelint plugins
- stylelint-config-rational-order 对关联属性进行分组和排序
- stylelint-declaration-block-no-ignored-properties 矛盾样式忽略
npm install stylelint-order stylelint-config-rational-order stylelint-declaration-block-no-ignored-properties -D
修改配置文件如下:
module.exports = {
extends: ['stylelint-config-standard', 'stylelint-config-rational-order'],
plugins: ['stylelint-order', 'stylelint-declaration-block-no-ignored-properties'],
rules: {
'plugin/declaration-block-no-ignored-properties': true,
'comment-empty-line-before': null,
'declaration-empty-line-before': null,
'function-name-case': 'lower',
'no-descending-specificity': null,
'no-invalid-double-slash-comments': null,
'rule-empty-line-before': 'always'
},
ignoreFiles: ['node_modules/**/*', 'build/**/*', 'dist/**/*']
};
解决 Stylelint 和 Prettier 的冲突
安装 stylelint-config-prettier
:
npm install stylelint-config-prettier -D
添加以下配置到 .stylelintrc.js 的 extends 中:
{
extends: [
// other configs ...
'stylelint-config-prettier'
]
}
lint 命令
我们在 package.json 的 scripts 中增加以下三个配置:
"scripts": {
"lint": "npm run lint-eslint && npm run lint-stylelint",
"lint-eslint": "eslint -c .eslintrc.js --ext .ts,.tsx,.js src",
"lint-stylelint": "stylelint --config .stylelintrc.js src/**/*.{less,css,scss}"
},
lint-staged
只针对 git 缓存区最新改动过的文件进行 格式化 和 lint 规则校验
husky
husky
可以提供一些钩子,比如执行 git commit
之前的钩子 pre-commit
,借助这个钩子我们就能执行 lint-staged
所提供的代码文件格式化及 lint
规则校验。
如果项目开始前没有初始化的.git
文件,要先初始化git,否则husky
会安装失败:
git init
安装 lint-staged
和 husky
:
npm install husky lint-staged -D
在 package.json
中添加以下代码:
{
"husky": {
"hooks": {
"pre-commit": "lint-staged",
}
},
"lint-staged": {
"*.{ts,tsx,js}": [
"eslint --config .eslintrc.js"
],
"*.{css,less,scss}": [
"stylelint --config .stylelintrc.js"
],
"*.{ts,tsx,js,json,html,yml,css,less,scss,md}": [
"prettier --write"
]
},
}
commitlint + changelog
在多人协作的项目中,如果 git 的提交说明精准,在后期协作以及 bug 处理时会变得有据可查,项目的开发可以根据规范的提交说明快速生成开发日志,从而方便开发者或用户追踪项目的开发信息和功能特性。
建议阅读 Commit message 和 Change log 编写指南(阮一峰)
commitlint
可以帮助我们在 git commit
时校验 message
格式是否符合规范,conventional-changelog
可以帮助我们快速生成 changelog
commitizen 可以在命令行中进行可视化的 git commit 操作,这里不作配置
安装 commitlint
相关依赖:
npm install @commitlint/cli @commitlint/config-conventional -D
@commitlint/config-conventional 类似 eslint
配置文件中的 extends
,它是官方推荐的 angular 风格的 commitlint
配置,提供了少量的 lint 规则
根目录新建文件 .commitlintrc.js
:
touch .commitlintrc.js
写入以下代码:
/**
* build : 改变了build工具 如 webpack
* ci : 持续集成新增
* chore : 构建过程或辅助工具的变动
* feat : 新功能
* docs : 文档改变
* fix : 修复bug
* perf : 性能优化
* refactor : 某个已有功能重构
* revert : 撤销上一次的 commit
* style : 代码格式改变
* test : 增加测试
* anno: 增加注释
*/
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
['build', 'ci', 'chore', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'anno'],
],
},
};
package.json
的 husky
配置,增加一个钩子:
{
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint --config .commitlintrc.js -E HUSKY_GIT_PARAMS"
}
},
}
-E HUSKY_GIT_PARAMS
简单理解就是会拿到我们的 message ,然后 commitlint 再去进行 lint 校验。
安装依赖changelog
:
npm install conventional-changelog-cli -D
在 package.json 的 scripts 下增加一个命令:
{
"scripts": {
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
},
}
之后就可以通过 npm run changelog
生成 angular 风格的 changelog
,需要注意的是,上面这条命令产生的 changelog
是基于上次 tag 版本之后的变更(feat
、fix
等等)所产生
测试:
# 提交所有变化到缓存区
git add -A
# 把暂存区的所有修改提交到分支
git commit -m "chore: add commitlint to force commit style"
git push origin master
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。