Monorepo 架构说明
Monorepo 架构说明
Monorepo 架构说明
本文档说明本仓库的目录结构、Workspaces 配置及日常使用方式。
一、架构概览
本仓库采用 npm Workspaces 的 Monorepo 结构:
- 根目录:只负责声明 workspaces、统一安装依赖,不发布到 npm(
private: true)。 - packages/:可复用的库包,可被应用或其他包依赖,可单独发布。
- dev/:应用或开发用项目,通常不发布,依赖 packages 中的包。
依赖安装只在根目录执行一次 npm install,各子包通过 workspace 链接互相引用。
二、目录结构
code-gen-monorepo/
├── package.json # 根 package,声明 workspaces,private: true
├── package-lock.json # 根锁文件,统一管理所有 workspace 依赖
├── .gitignore
├── docs/ # 文档
│ └── MONOREPO.md # 本说明文档
│
├── packages/ # 库包(可复用、可发布)
│ └── cg/ # 示例库包
│ ├── package.json # name: "cg"
│ ├── src/
│ │ └── index.ts
│ ├── dist/ # 构建产物(需先 build)
│ ├── tests/
│ ├── tsconfig.json
│ └── tsdown.config.ts
│
└── dev/ # 应用 / 开发项目
└── nest-admin-app/ # NestJS 应用
├── package.json # name: "nest-admin-app", 依赖 "cg": "*"
├── src/
│ ├── main.ts
│ ├── app.module.ts
│ └── ...
├── test/
├── tsconfig.json
└── nest-cli.json说明
| 路径 | 用途 |
|---|---|
根目录 package.json | 定义 workspaces: ["packages/*", "dev/*"],根包不发布 |
packages/* | 各子包为独立 npm 包,可被其他 workspace 或外部项目依赖 |
dev/* | 各子目录为应用或工具项目,通常依赖 packages/* 中的包 |
根目录 node_modules | 安装后大部分依赖会提升到此,子包多为链接 |
三、Workspaces 说明
3.1 根 package.json 中的配置
{
"private": true,
"workspaces": ["packages/*", "dev/*"]
}-
private: true
根包禁止被npm publish发布,避免误操作。 -
workspacespackages/*:将packages/下每个子目录视为一个 workspace(如packages/cg)。dev/*:将dev/下每个子目录视为一个 workspace(如dev/nest-admin-app)。
3.2 依赖安装与提升(Hoisting)
- 安装位置:在根目录执行一次
npm install即可。 - 行为:
- npm 会为所有 workspace 安装其
dependencies/devDependencies。 - 能兼容的依赖会提升到根目录的
node_modules。 - 子包目录下通常没有或只有少量
node_modules(链接或版本冲突时单独安装)。
- npm 会为所有 workspace 安装其
- 结论:不需要在
packages/cg或dev/nest-admin-app里再执行npm install。
3.3 子包引用方式(依赖 workspace 包)
应用要使用本仓库里的库包时,在应用自己的 package.json 里写依赖名和版本,不要用 npm install 包名 从 npm 安装同名包。
例如 dev/nest-admin-app 依赖本仓库的 packages/cg:
{
"dependencies": {
"cg": "*"
}
}"cg": "*"表示「使用当前仓库里名为cg的 workspace 包」。- 安装后,根目录或应用下的
node_modules/cg会链接到packages/cg,而不是从 npm 拉取。 - 若写
npm install cg且未在 package.json 里声明"cg": "*",则会从 npm 安装外部包,而不是本仓库的packages/cg。
注意:
workspace:*为 pnpm/Yarn Berry 协议,npm 不支持;使用 npm 时用"*"即可,npm 会解析为本地 workspace。
3.4 小结
| 概念 | 说明 |
|---|---|
| Workspaces 定义 | 根 package.json 的 workspaces: ["packages/*", "dev/*"] |
| 安装命令 | 仅在根目录执行 npm install |
| 依赖位置 | 主要安装在根目录 node_modules,子包多为链接 |
| 子包互依赖 | 在子包 package.json 中写 "包名": "*",指向本仓库同名 workspace |
四、常用操作
4.1 安装依赖
# 在仓库根目录执行
npm install4.2 构建库包(如 cg)
# 进入库包目录构建
cd packages/cg && npm run build
# 或从根目录(若根 package.json 有对应 script)
npm run build --workspace=cg应用依赖 cg 时,需先保证 packages/cg 已构建(存在 dist/),否则运行/构建应用可能报错。
4.3 运行应用(如 nest-admin-app)
# 进入应用目录
cd dev/nest-admin-app
npm run start:dev
# 或从根目录(若根 package.json 有对应 script)
npm run start:dev --workspace=nest-admin-app4.4 添加新的 workspace 包
- 在
packages/或dev/下新建目录,并包含合法的package.json(含name等)。 - 在根目录执行
npm install,npm 会自动识别新 workspace。
4.5 应用依赖库包
- 在应用的
package.json的dependencies中增加:"包名": "*"(如"cg": "*")。 - 在根目录执行
npm install。 - 确保被依赖的库包已构建(若有构建步骤)。
五、注意事项
- 根目录不要发布:根
package.json保持"private": true。 - 只用根目录安装:不要在子包目录执行
npm install,以免破坏 workspace 结构。 - npm 与 workspace 协议:使用 npm 时用
"cg": "*",不要用workspace:*(pnpm/Yarn 才支持)。 - 类型与构建:应用引用 workspace 包时,若出现「找不到模块/类型」:
- 确保该库包已执行过 build(如
packages/cg的dist/存在)。 - 库包
package.json的exports中建议包含types条件,便于 TypeScript 解析。 - 若仍无法解析,可在应用内增加本地类型声明(如
cg.d.ts)。
- 确保该库包已执行过 build(如
六、相关文件索引
| 文件 | 作用 |
|---|---|
根目录 package.json | workspaces 定义、根脚本、private |
packages/cg/package.json | 库包 cg 的入口、exports、构建脚本 |
dev/nest-admin-app/package.json | 应用依赖(含 "cg": "*")、应用脚本 |
docs/MONOREPO.md | 本说明文档 |