husky 和 lint-staged 应该算是在基于 node.js 的前后端项目中的标配了,它们可以帮助我们在提交代码时自动执行一些代码检查、格式化等操作,从而保证代码的质量。
在纯粹的前端或后端项目中,配置起来都很简单,但是在 monorepo 中,由于项目结构的复杂性,配置起来相对有些区别。这篇文章主要记录一下我的配置过程。
在我的项目中,使用 pnpm workspace 管理依赖,项目结构举例如下:
.
├── apps
│ ├── backend
│ │ ├── package.json
│ │ └── src
│ └── frontend
│ ├── package.json
│ └── src
├── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml
lint-staged
由于前后端采用的语言、技术和框架大概率不同,比如前端可能是 typescript
+ react
,后端可能是 typescript
+ express
,对于 eslint 等配置必然有所区别,所以并不建议在根目录下安装 lint-staged
,而是在各个子项目中安装。
pnpm -F backend add -D lint-staged
pnpm -F frontend add -D lint-staged
然后在各个子项目中配置 lint-staged
,backend
配置举例如下:
// backend/package.json
{
"lint-staged": {
"*.ts": ["eslint"]
}
}
frontend
配置举例如下:
// frontend/package.json
{
"lint-staged": {
"*.{ts,tsx}": ["eslint"],
"*.{css,scss}": ["prettier --write"]
}
}
husky
由于 husky
的原理是基于 git hooks,而一个 monorepo 中的 git hooks 只会在根目录下的 .git/hooks
中,所以 husky
应该安装在根目录下。
pnpm -w add -D husky
按照 官方文档 配置完成。
lint-staged + husky
我们需要在 .husky
-> pre-commit
中执行 lint-staged
相关的操作,为此我们需要在每个子项目的 package.json
中添加一个 script,用于执行 lint-staged
,举例如下:
// backend/package.json
{
"scripts": {
"lint-staged": "lint-staged"
}
}
// frontend/package.json
{
"scripts": {
"lint-staged": "lint-staged"
}
}
编辑 .husky
-> pre-commit
,添加如下内容:
##!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm -F backend run lint-staged
pnpm -F frontend run lint-staged
至此,无论是在前端还是后端项目中提交代码,都会自动执行 lint-staged
,从而保证代码质量。而且 lint-staged
的配置分散在各个子项目中,可以按照各自的需求配置如 prettier
、stylelint
等,互不干涉,非常灵活。