从0开始monorepo

目前业界最流行的组合是:pnpm Workspaces 作为底层依赖管理,搭配 Turborepo 作为任务编排。

以下三者并不是互斥关系,而是互补的层级关系:

  1. pnpm Workspaces(基础层):

    • 定位: 解决“依赖怎么装、包之间怎么引用”的问题。
    • 现状: 它已经是现代 Monorepo 的事实标准。由于它利用硬链接节省磁盘空间且速度极快,Turborepo 和 Nx 官方都推荐优先使用 pnpm 作为包管理器。
  2. Turborepo(流行趋势):

    • 定位: 解决“怎么高效构建、怎么并行跑任务、怎么缓存”的问题。
    • 现状: 目前最流行。它由 Vercel 维护,理念极简(只需要一个 turbo.json),侵入性极低,特别适合混合 Vue/React/Node 的项目,且 Remote Caching 功能对团队协作提升巨大。
  3. Nx(重型武器):

    • 定位: 不仅是构建工具,更是一个“开发平台”,提供代码生成、依赖图可视化、AI 辅助等。
    • 现状: 功能最强大,但相对较重。更适合大型企业团队(几十人以上)或 Angular/React 全家桶项目,对于单纯混合 Vue/React 的轻量级场景,Turborepo 通常是更主流的选择。

总结选型建议

  • 90% 的场景(推荐): pnpm Workspaces + Turborepo
  • 大型企业/需要强约束: pnpm Workspaces + Nx

本期记录整理 pnpm Workspaces + Turborepo 流程

第一步:环境准备 & 初始化

  1. 安装 pnpm

    1
    npm install -g pnpm
  2. 创建项目根目录

    1
    2
    mkdir monorepo-template
    cd monorepo-template
  3. **初始化根 package.json**:

    1
    pnpm init
  4. 新建 pnpm-workspace.yaml 文件
    在根目录创建此文件,否则执行第5步会报错

  5. 安装 Turborepo
    在根目录安装 Turborepo 为开发依赖:

    1
    pnpm add -Dw turbo

    注:-w 代表 workspace-root,即安装在根目录。


第二步:配置核心文件

1. 配置 pnpm-workspace.yaml

告诉 pnpm 哪些目录是子包:

1
2
3
4
# pnpm-workspace.yaml
packages:
- 'apps/*' # 所有应用 vue/react/nodejs项目
- 'packages/*' # 所有共享库 utls/types/components

2. 配置 turbo.json

在根目录创建此文件,定义任务流水线:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"tasks": {
"build": {
// 依赖于依赖包的 build
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
},
"dev": {
// dev 不需要依赖 ^dev,通常并行启动
"cache": false,
"persistent": true
},
"lint": {
"dependsOn": ["^lint"]
}
}
}

3. 修改根 package.json

添加一些快捷脚本和配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"name": "monorepo-template",
"version": "1.0.0",
"description": "a monorepo template",
"main": "index.ts",
"scripts": {
"dev": "turbo dev",
"build": "turbo build",
"lint": "turbo lint",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "csorz",
"license": "MIT",
"packageManager": "pnpm@10.32.1",
"devDependencies": {
"turbo": "^2.8.17"
},
"engines": {
"node": ">=20"
}
}


第三步:创建目录结构

手动创建以下文件夹结构:

1
2
3
4
5
6
monorepo-templat/
├── apps/ # 存放可运行的应用
├── packages/ # 存放共享的工具库
├── package.json
├── pnpm-workspace.yaml
└── turbo.json

第四步:创建子项目

创建项目:

  1. packages/utils: 共享的 JS/TS
  2. apps/vue3: vue3 应用
  3. apps/react19: React19 应用