1.vite创建项目
我的技术栈是react,因此创建项目时有2种选择:
- 1.使用create-react-app创建
- 2.基于vite创建,目前5.2.0版本(2024.04.07)
推荐使用基于vite创建,因为vite是基于浏览器 es module import 实现的编译服务,而CRA底层是基于webpack编译打包,多了打包环节,开发时界面响应速度就慢,具体可参考vite实现原理
在创建时推荐使用pnpm包管理工具,具体原因在这,创建命令是: pnpm create vite frontend --template react-ts ,该模版来自这里
2.代码质量工具
eslint侧重检查js语法错误,prettier侧重格式化代码样式,stylelint侧重css代码检查
在vite创建React项目时就已经内置了ESlint
1.首先初始化eslint,执行
pnpm create @eslint/config会生成.eslintrc.cjs 配置文件:
这里执行pnpm create @eslint/config相当于执行pnpm eslint --init,使用的eslint版本为"eslint": "^8.57.0",在eslint>=8.23.0时使用eslint.config.js配置文件而不是.eslintrc.cjs文件,具体说明来自这里,但也能兼容
执行结果如下:
可以看到生成的配置文件继承了
'eslint:recommended','plugin:@typescript-eslint/recommended','plugin:react-hooks/recommended',如果需要配置 lint 规则可以在 rules 中添加,此时自动生成的.eslintrc.cjs文件包含以下内容:
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',// ESLint 官方推荐的规则集
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
此时在App.tsx中删除return中的内容后,会在上面发现'useState' is defined but never used.eslint[@typescript-eslint/no-unused-vars](https://typescript-eslint.io/rules/no-unused-vars),说明此时eslint开始起作用了
但是会发现此时package.json中自动添加了一个lint的脚本 "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",当执行pnpm run lint时会报错:
这是因为在最新的ESLint版本中,
--ext命令行选项不再可用,文件扩展名应通过配置文件中的files属性来指定,而不是在命令行中指定。
export default {
// ...
files: ["**/*.{ts,tsx}"],
// ...
};
将命令修改成"lint": "eslint . --report-unused-disable-directives --max-warnings 0"此时再执行pnpm run lint时,结果如下:
会发现.eslintrc.cjs根本不需要eslint检测,直接将其忽略
/* eslint-disable */后再去执行
2.接着来安装prettier:
pnpm i prettier -D
然后在根目录创建 .prettierrc.cjs 配置文件
module.exports = {
// 每行最大列,超过换行
printWidth: 120,
// 使用制表符而不是空格缩进
useTabs: false,
// 缩进
tabWidth: 2,
// 结尾不用分号
semi: false,
// 使用单引号
singleQuote: true,
// 在JSX中使用单引号而不是双引号
jsxSingleQuote: true,
// 箭头函数里面,如果是一个参数的时候,去掉括号
arrowParens: "avoid",
// 对象、数组括号与文字间添加空格
bracketSpacing: true,
// 尾随逗号
trailingComma: "none",
};
在App.tsx添加 ";" 执行以下命令测试pnpm prettier --write ./src/App.tsx ,会发现文件被自动修复
3.接下来在 ESLint 中引入 Prettier,安装相关依赖:
虽然已经安装了eslint和prettier,但为了让ESLint能够在执行时调用Prettier进行代码格式化的检查和修正,就需要在ESLint配置文件中集成Prettier的规则。
pnpm i eslint-config-prettier eslint-plugin-prettier -D
其中eslint-plugin-prettier 是将 Prettier 的代码格式化规则转化为 ESLint 可以识别和执行的规则,eslint-config-prettier 是关闭或忽略 ESLint 中与 Prettier 产生冲突的格式化相关的规则
然后更改 Eslint 的配置文件 .eslintrc.cjs 在里面加入 Prettier 相关配置。具体含义在这
module.exports = {
// 其他ESLint配置...
extends: [
// ...其他继承的规则集
'plugin:prettier/recommended', // 引入Prettier的推荐规则
],
plugins: [
// ...其他插件
'prettier', // 添加Prettier插件
],
rules: {
// 确保Prettier规则优先级最高
'prettier/prettier': 'error',
// 其他自定义规则...
},
};
同样在App.tsx中添加";"后执行pnpm run lint命令,就会调用prettier:
可以更改eslint脚本,加上自动修改
"lint": "eslint . --report-unused-disable-directives --max-warnings 0 --fix",
4.在 Vite 中引入 ESLint 插件,以便在开发阶段发现问题,自动触发eslint。
首先安装依赖pnpm i vite-plugin-eslint -D ,然后在 vite.config.ts 引入插件
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import viteEslint from 'vite-plugin-eslint'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
viteEslint({
failOnError: true
})
]
})
此时会发现它在报类型错误无法找到模块“vite-plugin-eslint”的声明文件。这需要等待作者修复,临时方案是先忽略它:
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
import viteEslint from 'vite-plugin-eslint'
此时同样在App.tsx中添加";",现在就可以在运行时的控制台看到 ESLint 报错了。
如果想要在发现错误时自动修复,可以添加以下配置:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
import viteEslint from 'vite-plugin-eslint'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
viteEslint({
fix: true,
failOnError: true,
include: ['src/*.ts', 'src/*.tsx', 'src/**/*.ts', 'src/**/*.tsx']
})
]
})
这样在出错时,当command+s保存时就会自动修复了
5.添加 stylelint 检查 css 代码 首先安装依赖:
pnpm i -D stylelint stylelint-config-standard
接着通过pnpm create stylelint初始化,它会在根目录下生成.stylelintrc.json配置文件
其配置如下:
{
"extends": [
"stylelint-config-standard"
]
}
此时运行npx stylelint "**/*.css"结果如下:
将自动修改加上后重新运行:
npx stylelint "**/*.css" --fix
它也需要在运行时自动检测并修复,所以也需要集成到vite的配置文件中,先来安装所需要的依赖
pnpm i -D stylelint stylelint-config-standard vite-plugin-stylelint
接着在Vite配置文件中添加vite-plugin-stylelint插件:
// 集成stylelint运行时检测修复
import stylelint from 'vite-plugin-stylelint'
import stylelintConfig from './.stylelintrc.json'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
// ...
stylelint({
// 配置stylelint选项
config: stylelintConfig,
// stylelint的文件范围
include: ['src/**/*.{css,scss,less,tsx,html}']
})
]
})
此时App.css文件故意改错,然后运行pnpm run dev,结果如下:
body {
color: invalid-color-name;
}
加上自动修复fix: true,此时会发现报另外一个错误: Unexpected empty source no-empty-source
这是因为index.css中没有任何的css内容,但希望忽略这条规则,可以在配置文件中将该规则关闭
{
"extends": [
"stylelint-config-standard"
],
"rules": {
"no-empty-source": null
}
}
再来运行时就不会报错了
3.提交规范
在提交前需要对代码自动进行检查,
1.通过 Husky 在 Git commit 时进行代码校验,它本质是git的钩子
先安装依赖: pnpm i husky -D
然后初始化: pnpm exec husky init,它会添加"prepare": "husky"脚本命令,并且在根目录下生成.husky目录,其中pre-commit钩子中有pnpm test,意味着在git commit时会自动执行test脚本命令,但此时并没有test脚本命令,我希望自己编写一个,在执行它时会依次进行eslint和stylelint检测,其中eslint检测的命令为"lint:eslint": "eslint . --report-unused-disable-directives --max-warnings 0 --fix",stylelint检测命令为 "lint:stylelint":"",如何把他们集中到test命令?
"scripts":{
"lint:eslint": "eslint . --report-unused-disable-directives --max-warnings 0 --fix",
"lint:stylelint": "stylelint \"**/*.{css,scss,less,tsx }\"",
"test": "npm-run-all lint:*"
},
"husky": {
"hooks": {
"pre-commit": "pnpm test"
}
},
可以看到集成了lint:eslint,lint:stylelint和test三个脚本指令,并且添加了husky指令,此时如果故意改错一些格式,然后执行git commit
会发现此时报错
sh: npm-run-all: command not found,但是husky - pre-commit script failed (code 1)钩子已经触发了,只需要安装了 npm-run-all 包即可解决pnpm install npm-run-all -D,此时执行git commit结果如下:
- 通过 lint-staged 只对暂存区的代码进行检验。
首先安装依赖: pnpm i lint-staged -D
然后在 package.json 添加相关配置:
{
"scripts": {
"lint:stylelint": "stylelint \"**/*.{css,scss,less,tsx }\" --fix",
"lint-staged":"lint-staged"
},
"lint-staged": {
"*.{js,jsx,tsx,ts}": [
"pnpm run lint:eslint",
],
"*.{css,scss,less}": [
"pnpm run lint:stylelint",
]
},
}
接着在pre-commit文件中修改命令:pnpm run lint-staged后再来执行:
- 使用 commitlint 对提交信息进行校验。 先安装依赖:
pnpm i @commitlint/{cli,config-conventional} -D
然后在根目录创建配置文件 commitlint.config.js
export default {
extends: ['@commitlint/config-conventional']
}
然后把 commitlint 命令添加到 Husky commit-msg钩子。
运行命令:echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg,这样在.husky目录下就会添加commit-msg,内容为npx --no -- commitlint --edit $1
现在提交信息不合法就会被拦截导致提交失败,规范可见 commitlint ,也可以根据需要修改提交信息规范。
可以看到由于不符合提交信息规范,本次commit就被终止了,具体规范如下:
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
因此上面的信息要改成git commit -m "chore(commitlint): 添加commitlint用于检测合法提交信息"后再来提交
4.vscode设置
通过.editorconfig实现在不同的开发环境中遵循同一套代码格式标准
# https://editorconfig.org
root = tue
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
此时可通过编辑器自带的功能检查是否生效:
5.强制使用pnpm
pnpm可以锁文件且可复用依赖,团队开发时强制使用pnpm,为了实现强制效果,原理是在使用包管理工具install的时候会触发preinstall(npm提供的生命周期钩子),只需在此拦截只允许使用pnpm即可
首先在根目录创建scripts/preinstall.js文件,添加下面的内容:
/* eslint-env node */
console.log(process.env.npm_execpath)
if (!/pnpm/.test(process.env.npm_execpath || '')) {
console.warn(`Oops,同学,当前模版只能使用pnpm包管理工具`)
process.exit(1)
}
然后在package.json的scripts中添加 "preinstall": "node ./scripts/preinstall.js" 此时若是用npm或其他工具进行安装时就会报错终止,提示必须使用pnpm