使用 pnpm workspace 搭建 Vue MVP 的 monorepo 结构
2025-09-14 13:17:28
这一篇先把项目结构搭起来。
如果只是写一个响应式 demo,一个 index.ts 就够了。但这个系列后面还会继续实现运行时和编译时,如果所有代码都堆在一起,很快就会变得不好维护。
所以第一步先使用 monorepo 拆分模块,让每个包只负责一件事。
2025 年了,我不允许你还不会 monorepo
为什么使用 Monorepo
monorepo 指的是在一个 Git 仓库里管理多个相互关联的包。
可以把它理解成一个工厂:里面有多个独立的流水线(子项目),但每一个流水线都有共用的一套标准化工具和基础设施
Monorepo 和 Multi-repo
| 维度 | Monorepo | Multi-repo |
|---|---|---|
| 仓库数量 | 一个仓库管理多个包 | 多个仓库分别管理 |
| 本地调试 | 可以直接引用 workspace 包 | 通常需要发布、link 或额外配置 |
| 版本对齐 | 更容易统一修改和提交 | 跨仓库同步成本更高 |
| 工具配置 | 可以共享构建、测试、格式化配置 | 每个仓库都需要维护一份 |
目录设计
先规划一个可用目录:
packages/
reactivity/
runtime-core/
runtime-dom/
shared/
reactivity:实现ref、reactive、effect、computedruntime-core:实现 vnode、组件实例、调度器和通用渲染流程runtime-dom:实现 DOM 平台的render、createElementshared:实现isObject、isFunction、hasChanged这类通用工具
配置 pnpm workspace
在根目录创建 pnpm-workspace.yaml:
packages:
- packages/*
这段配置的含义是:packages 目录下的每一个子目录都可以作为一个独立 workspace 包。
先创建这两个包:
packages/reactivity
packages/shared
安装公共依赖
typescript 属于整个项目都会用到的开发依赖,所以安装到 workspace 根目录:
pnpm add typescript -D -w
pnpm add @types/node -D -w
配置 tsconfig
{
"compilerOptions": {
"target": "ESNext",
// 指定 ECMAScript 目标版本
"module": "ESNext",
// 指定模块代码生成规范
"moduleResolution": "node",
// 指定模块解析策略
"outDir": "dist",
// 指定编译输出的目录
"resolveJsonModule": true,
// 允许导入 JSON 文件
"strict": false,
// 关闭严格模式
"lib": [
"ESNext",
"DOM"
],
// 指定要使用的库文件
"paths": {
"@vue/*": [
"packages/*/src"
]
},
"baseUrl": "./"
}
}
这里最重要的是 baseUrl 和 paths:
{
"baseUrl": "./",
"paths": {
"@vue/*": [
"packages/*/src"
]
}
}
这段配置让 TypeScript 能识别 @vue/shared、@vue/reactivity 这种包名引用,并把它们映射到本地的 packages/*/src 目录。