1. pnpm deploy「官方方案」
核心理念: 物理提取,按需隔离
1. 构建流
pnpm fetch: 仅基于pnpm-lock.yaml下载依赖到虚拟存储层。只要依赖清单未变,该层将实现极致的 Docker 缓存命中pnpm install --offline: 拷贝源码后强制离线安装。完全跳过网络请求,利用本地缓存高速装配环境pnpm deploy: 将指定子包从 Workspace 中"抽取"到独立目录,并将原有的内容寻址链接自动转换为真实的物理文件
2. 致命缺点
- 孤岛效应 :
deploy后的目录呈绝对隔离状态,不会自动携带 根目录的非依赖文件(如tsconfig.base.json、.eslintrc),导致基于相对路径的配置继承失效 - 工具缺失 :若构建脚本依赖根目录的共享工具(如
rimraf),必须在每个子包的devDependencies中显式声明,否则隔离后的环境将无法识别指令
2. Hoisted 「补丁方案」
核心理念: 结构模拟,路径桥接
1. 依赖平铺模式
ini
pnpm install --node-linker=hoisted
- 强制 pnpm 放弃网格化链接结构,将所有依赖(含各子包依赖)平铺安装至根目录
/app/node_modules - 彻底消除 Docker 镜像构建中常见的软链接解析失效问题,使文件系统回归经典的
物理路径可达状态
2. 重建路径链路
由于依赖被"提升"到了根目录,而子包(Packages)的代码物理位置仍在深层目录,因此需要通过两个关键补丁来修复逻辑断层:
- 目录映射 Symbolic Link
bash
RUN ln -s /app/node_modules /app/packages/node_modules
在子包层级的人为创造一个指向根目录依赖的入口。完美修复源码中通过相对路径(如 @import '../node_modules/') 引用依赖时的解析报错
- 执行上下文 PATH Injection
ini
// 将根目录的可执行脚本库注入系统全局变量
ENV PATH=/app/node_modules/.bin:$PATH
将根目录的 .bin 可执行脚本库注入系统全局变量。确保在任意子包目录下执行 ng build 或 vite 时,系统能跨目录精准定位指令
3. 技术选型对比
| 维度 | 官方方案 (Deploy) | 补丁方案 (Hoisted) |
|---|---|---|
| 设计取向 | 子包独立化:将子包视为独立微服务 | 仓库整体化:保持 Monorepo 完整上下文 |
| 配置共享 | 困难:需手动 cp 补齐父级配置文件 | 原生支持:天然支持相对路径配置继承 |
| 安全性 | 高:严控幽灵依赖,运行环境纯净 | 中:依赖平铺可能引入隐式依赖风险 |
| 适用场景 | 子包可完全独立部署、无外部配置依赖 | 强耦合、重度共享配置的 Monorepo 项目 |