Monorepo实战总结:从踩坑到高效管理多项目经验分享
我的写法,亲测靠谱
在使用Monorepo的过程中,我总结了一些实战经验。这些经验都是我在实际项目中踩过坑、调整过的,希望能对你有所帮助。
Monorepo的目录结构
首先,我们来说说Monorepo的目录结构。这一步非常关键,一个好的目录结构能让你的项目更清晰,维护起来也更方便。
我一般这样处理:
my-monorepo/
├── packages/
│ ├── app1/
│ ├── app2/
│ ├── shared-utils/
│ └── ...
├── scripts/
├── configs/
├── .gitignore
├── lerna.json
├── package.json
└── README.md
这种结构的好处是每个应用或库都有自己的目录,共享工具和脚本放在单独的目录里,这样可以避免文件混乱。
建议避开在一个大目录下放所有东西,容易出问题,特别是当你有多个应用或库时,管理起来会非常麻烦。
包管理工具的选择
在Monorepo中,选择合适的包管理工具非常重要。我用的是Lerna,它非常适合管理多包项目。
这里是我的配置文件lerna.json:
{
"packages": ["packages/*"],
"version": "0.0.0",
"npmClient": "yarn",
"useWorkspaces": true,
"command": {
"publish": {
"conventionalCommits": true
}
}
}
为什么用Lerna?因为它可以帮助你管理版本、发布包,还能自动处理依赖关系。不过,也有一些反面案例需要注意。
比如,如果你不设置useWorkspaces: true,那么Lerna不会利用Yarn的工作空间功能,这样会导致依赖安装变得很慢。
工作空间的配置
说到工作空间,Yarn的工作空间功能是非常强大的。我一般这样配置package.json:
{
"name": "my-monorepo",
"private": true,
"workspaces": [
"packages/*"
],
"scripts": {
"bootstrap": "lerna bootstrap",
"build": "lerna run build",
"test": "lerna run test"
}
}
这样配置后,你可以通过一个命令同时运行所有包的构建或测试任务。这个写法更靠谱,因为你可以一次性完成所有子项目的操作,而不是一个个手动去跑。
常见的错误写法是直接在每个包的package.json里定义一堆脚本,然后手动执行。这种方式不仅麻烦,还容易出错。
实际项目中的坑
在实际项目中,我也遇到过一些坑。这里分享几个给你:
- 依赖冲突:当多个包依赖同一个第三方库的不同版本时,可能会出现冲突。解决方法是尽量统一依赖版本,或者使用
resolutions字段来强制指定版本。 - 脚本执行顺序:有时候,你需要确保某些脚本按特定顺序执行。例如,先构建某个库再构建应用。这时可以使用
npm-run-all等工具来控制脚本顺序。 - CI/CD集成**:在CI/CD中,确保你的脚本能够正确运行。有时候,CI环境可能缺少某些依赖,需要在CI配置文件中明确指定。
我曾经因为这些问题折腾了半天才发现问题所在,所以特别提醒一下。
一些反面案例,别再踩坑了
最后,分享一些我见过的反面案例,希望你能避开这些坑。
- 过度复杂化:有些人喜欢把Monorepo搞得非常复杂,引入各种工具和插件。其实,简单点更好,复杂的东西往往更难维护。
- 忽略版本管理**:在Monorepo中,版本管理非常重要。有些团队忽略了这一点,导致版本混乱。建议使用Lerna的版本管理功能,结合Conventional Commits规范,让版本管理自动化。
- 缺乏文档**:Monorepo的结构和配置往往比较复杂,如果缺乏文档,新成员很难上手。建议在项目中加入详细的README文件,解释每个部分的作用和使用方法。
以上是我总结的最佳实践,有更好的方案欢迎评论区交流。希望这些经验能帮到你!
