vue3 + typescript + eslint + husky + pnpm
统一化团队的代码风格,样式,git规范等
概览
一般前端基建包括以下内容:
- 基本语言:javascript、Typescript
- 环境配置:env文件内容注入
- 打包构建工具:例如Webpack、Rollup、vite等;
- 包管理工具:例如npm、Yarn、pnpm等;
- 前端框架:例如React、Vue.js等;
- 代码质量工具:例如ESLint、Prettier等;
- 单元测试:例如Jest、Mocha等;
- HTTP请求库:例如Axios、Fetch等;
- 状态管理工具:例如Redux、Mobx、vuex、pinna等;
- UI组件库:例如Ant Design、Element UI、自建组件库等;
- 前端性能分析工具:例如Lighthouse、WebPageTest等;
- 应用部署与自动化工具:例如Docker、Travis CI等。
monorepo项目搭建
现在很大一部分框架都采用了pnpm进行多包的管理,例如vue,element-plus等
官方文档:https://pnpm.io/zh/motivation
具体事项不再细说,本文章主要目的是手把手的操作与记录。
pnpm安装
个人建议pnpm全局安装,更加的方便
1 | # 全局安装pnpm |
项目搭建
pnpm-workspace.yaml定义了工作空间的根目录,并能够使您从工作空间中包含 / 排除目录 。默认情况下,包含所有子目录。
在项目根目录初始化和创建pnpm-workspace.yaml文件,并填入示例内容
1 | pnpm init |
1 | touch pnpm-workspace.yaml |
示例:
1 | # pnpm-workspace.yaml |
假定我们的模块分块是core,utils,components,那么就可以在packages目录下分别新建这三个文件夹,分别执行pnpm init去生成对应package.json文件
示例:其他模块同理,这里不再赘述
1 | cd packages |
node_modules扁平化的问题
pnpm的node_modules结构是非扁平化的,而npm和yarn采用了平铺的node_modules结构,平铺结构的一个较明显的问题是幽灵依赖,即在package.json中没有定义,但是我们可以导入使用的依赖。
如果需要pnpm将node_modules平铺,根目录新建.npmrc文件,填入shamefully-hoist=true
1 | # .npmrc |
typescript
typescript的安装一般会选择跟随项目,即在项目内安装typescript,避免不同typescript版本导致的兼容性问题
安装和初始化
全项目ts,安装在根目录即可
1 | pnpm add typescript -Dw |
初始化,操作完成后执行目录会生成一个tsconfig.json
1 | npx tsc --init |
tsconfig
参考element-plus,为了提高tsconfig的扩展性,提供tsconfig.base.json,tsconfig.web.json, tsconfig.json等文件,tsconfig.json主要作为一个入口,用于引用其他tsconfig文件
1 | // tsconfig.base.json |
1 | // tsconfig.web.json |
总入口
1 | // tsconfig.json |
测试
项目根目录执行
1 | npx tsc --build tsconfig.json |
在根目录生成了dist文件夹,内部结构与packages一致,同时具有js文件和d.ts声明文件
eslint
安装和初始化
1 | pnpm add eslint -Dw |
1 | pnpm create @eslint/config |
这里笔者选择的是To check syntax and find problems
1 | ? How would you like to use ESLint? … |
使用的是es6规范,所以选择javascript modules,要看自己项目需求
1 | ? What type of modules does your project use? ... |
看自己项目需求
1 | ? Which framework does your project use? … |
使用ts?
1 | Does your project use TypeScript? » No / Yes |
两个都选
1 | ? Where does your code run? ... (Press <space> to select, <a> to toggle all, <i> to invert selection) |
配置文件格式
1 | ? What format do you want your config file to be in? ... |
笔者选择了yes
1 | eslint-plugin-vue@latest @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest |
后续的可以根据项目需求调整即可,最后生成.eslint.js文件
项目根目录安装下列eslint插件
1 | pnpm add eslint-plugin-vue @typescript-eslint/eslint-plugin@latest -Dw |
.eslintrc.js & .eslintignore
1 | // .eslintrc.js |
.eslintignore文件是一个纯文本文件,每一行都是一个glob模式告知eslint忽略哪些文件或者目录
1 | # .eslintignore |
测试
根目录package.json新增脚本,目前只需要校验packages里面的ts文件,具体文件需要根据项目需求进行配置
1 | { |
在index.ts内定义了const a = 1,故意不带分号,eslintrc里面设置了不带分号就报错
1 | pnpm lint |
这个时候可以运行pnpm lint:fix进行修复
1 | pnpm lint:fix |
vscode eslint设置
生效的前提是必须去vscode的扩展商店安装eslint插件
1 | // .vscode/settings.json |
husky & commitlint
husky是前端工程化的一个重要工具,可以方便的向项目中添加git hooks,一般在commit之前校验代码,commit的时候检验commit信息是否符合规范,而且设置简单。
husky安装和初始化
1 | pnpm add husky -Dw |
package.json中添加prepare脚本,执行git init,再执行pnpm prepare
1 | { |
执行完上述命令后,根目录会存在一个.husky文件夹,接下来执行以下命令,在commit的时候,就会自动运行pnpm lint,如果lint不通过,将会终止git commit。
1 | npx husky add .husky/pre-commit "pnpm lint" |
如果git commit因为代码校验不通过而被终止,这时候可以通过pnpm lint:fix进行代码自动格式化,通过代码校验后即可以再次commit
commitlint安装和初始化
commitlint的作用是校验commit信息的规范性,官方提供了对应commit信息的模板,类似于git commit -m “test” 这类的commit是无法通过校验的。
一般要求的格式是
- feat: xxx
- fix: xxx
- docs: xxx
官方文档:https://commitlint.js.org/#/reference-prompt
示例
1 | git commit -m "feat: add some feature" |
安装和初始化
安装
1 | pnpm add @commitlint/cli @commitlint/config-conventional -Dw |
设置commitlint需要遵循的规范,在根目录创建commitlint.config.js,填入以下内容
1 | module.exports = { |
配合husky使用
1 | npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}' |
测试
首先故意设置const a = 1 不带分号,导致pre-commit终止
1 | > eslint --ext .ts packages/ |
运行pnpm lint:fix修复,修复后提示a未被使用,但是没有error
1 | > eslint --ext .ts packages/ --fix |
再次提交commit,故意不按照commit规范
1 | git add . |
此时提示commit-msg hook error
1 | ⧗ input: test commit-msg hook |
修改commit msg,校验通过
1 | git commit -m "test: test commitlint" |
1 | feat/initial 6490b0c] test: test commit lint |
总结
本文的内容相对基础,主要是总结一下具体的用途和解决方案,并非很详细的教学内容,如果需要高级的用法,最好的方法还是通过官方文档,去学习如何配置,高级用法等。
下一篇计划开始编写与环境配置、构建相关的内容。