为什么使用Monorepo
公司前端项目大大小小也有数十个了,每个项目都是独立的一个仓库地址,典型的Mutiplerepo
随着项目增多,发现每次起新项目都要重新创建模板然后定义一些项目框架然后在着手开发。
痛点:
- 每次新项目都需要重新搭建工程
解决: - 用cli做了一键生成项目脚手架解放了一部分劳动力,这个是基于仓库的template模板工程
又来一个痛点:
- 很多开发过程中的关于基础建设的idea都被封存在各自的项目里,导致template工程没有人持续维护,基本维持刚开始的样子,导致脚手架逐渐落后。
解决:
- Monorepo 管理方案,可以很大程度改善以上的问题
也方便做很多代码风格质量以及ci相关流程的统一管理,决定也搭建一套自己的Monorepo工程模板
开始
为什么使用pnpm?
pnpm 的特点:快速、高效利用磁盘空间。
它将 workspace 的所有依赖都下载到.pnpm
目录下,然后再根据各个 package 的情况,在其目录下通过软连接方式将依赖添加进来,这样所有的依赖只需要下载一次,那么不仅快,而且磁盘体积也小
而且它原生 cli 支持基本的 workspace 管理,这也是我对比下来选择 pnpm 的原因
学习成本低、简单好用
安装pnpm
npm install -g pnpm
创建workspace
pnpm init
根目录创建pnpm-workspace.yaml
packages:
- "libs/**"
- "projects/**"
创建自己的目录结构
├── libs
│ ├── core
│ │ ├── package.json
│ │ └── pnpm-lock.yaml
│ ├── ui
│ │ ├── package.json
│ │ └── pnpm-lock.yaml
│ ├── util
│ │ ├── package.json
│ │ └── pnpm-lock.yaml
├── projects
│ ├── demo
│ │ ├── package.json
│ │ └── pnpm-lock.yaml
├── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml
现在基本上我们已经有一个 mini 版的 workspace 了,至少整个目录结构看上去像那么回事。
使用pnpm cli 管理 workspace
1、配置依赖
比如我们的 core
包:
- 各种 Base类
- Http
那么我们需要给 core 安装 axios 以及 qs
比如我们的 demo
工程:
- vue
- vite
以及我们的全局生效的依赖:
- eslint
- mocha
- nyc
- typescript
- ...
这里因为该 Monorepo 都是 vue3 + vite
相关技术栈,所以我把相关依赖也一并安装到 root,这样以后新建的 project 就不用重新安装依赖啦!
2、安装依赖
cd libs/core && pnpm i
?
No No No!
pnpm 早就帮我们考虑到了,直接根目录就可以指定安装子包的依赖
-F, --filter <package_name>
可以指定目标 package 执行任务
pnpm i -F core
那问题来了,如果多个包都配置好了依赖,想要一键安装怎么办,一个一个包去这样做吗?
还是说pnpm i -F core ui util
三个还好说,三十个呢?
这个时候我们需要了解一下 -r, --recursive 命令可以做到一键递归安装
pnpm i -r
3、根目录执行命令
除了一些全局生效的命令之外,像我们可以按需求配置执行 project 的启动和打包
// root pkg.json
"script": {
"dev:demo": "pnpm -F demo dev",
"build:demo": "pnpm -F demo build"
}
// demo pkg.json
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview"
}
4、project 关联 libs
安装好依赖之后,我们可以简单写一点代码到core包里面,比如:
// index.ts
export function add(a: number, b: number) {
return a + b;
}
然后我们在demo工程里执行 pnpm i @libs/core -F demo
我们会发现 demo 的 pkg.json 多了这个
{
"dependencies": {
"@libs/core": "workspace:*", // * 代表默认同步最新版本,正常安装完应该是 ^1.0.0
}
}
我们尝试在文件中导入 core 中 add 方法
import { add } from "@libs/core";
console.log(add(1, 2));
我们就已经成功在项目中引入 libs/core 了
总结
我们通过以上步骤已经可以搭建出一个完整的 Monorepo 工程项目了,接下来就是不断补充内容,丰满羽翼,争取早日投入到生产实践中
网友评论