2025.09.01

环境构建:从零到一建立 Monorepo 工作流

🚀 快速开始

通过以下步骤,你将从零搭建一个可扩展、可维护的 Monorepo 工作区。

步骤 1️⃣:项目初始化

命令目的
pnpm init初始化根目录 package.json
mkdir -p packages创建用于存放所有子包的 packages 目录
cat > pnpm-workspace.yaml <<'YAML'创建 pnpm-workspace.yaml,定义包的查找路径

pnpm-workspace.yaml 内容:

packages:
  - packages/*

步骤 2️⃣:TypeScript 配置

  1. 安装 TypeScript(工作区层级)
     pnpm add -D typescript -w
    

    pnpm-w ( --workspace-root ) 标志确保依赖安装在根目录。

  2. 初始化 tsconfig.json
     npx tsc --init
    

推荐 tsconfig.json 配置

{
  "compilerOptions": {
    /* 基础配置 */
    "target": "ESNext",
    // 目标 JS 版本
    "module": "ESNext",
    // 模块代码生成规范
    "moduleResolution": "node",
    // 模块解析策略(兼容 Node.js)
    "lib": [
      "ESNext",
      "DOM"
    ],
    // 指定使用的标准库
    /* 编译输出 */
    "outDir": "dist",
    // 指定编译输出的目录
    /* 模块增强 */
    "resolveJsonModule": true,
    // 允许导入 JSON 文件
    "strict": false,
    // 暂时关闭严格模式,方便快速迭代
    /* Monorepo 路径别名(关键配置) */
    "baseUrl": "./",
    "paths": {
      "@vue/*": [
        "packages/*/src"
      ]
      // 别名映射:如 @vue/shared 映射到 packages/shared/src
    }
  }
}

配置 paths 以实现 包间的路径别名导入 (@vue/shared -> packages/shared/src),这是 Monorepo 的重要优势。

步骤 3️⃣:目录结构搭建

为了模仿 vue 项目, 创建核心包

  mkdir -p packages/shared/src packages/reactivity/src packages/vue/src

为了拥有 Vue 一样的构建和发布体验,需要将 package.json 模板 复制到每个子包中。

步骤 4️⃣:引入开发工具链

为了提高开发效率、代码质量和发布流程的自动化, 引入以下工具:

工具目的安装命令
ESLint&Prettier统一代码风格和规范pnpm add -D eslint prettier -D
Changesets专业的版本管理和自动化发包工具。pnpm add -D @changesets/cli -w && pnpm changeset init
Turbo高性能的任务编排和缓存加速工具。pnpm add -D turbo -w

📁 最终的项目结构

monorepo/
├── packages/
│   ├── shared/          # 共享工具库
│   │   └── src/
│   ├── reactivity/      # 响应式系统
│   │   └── src/
│   └── vue/            # 主框架: 聚合 Reactivity、Compiler 等模块
│       └── src/
├── pnpm-workspace.yaml
├── tsconfig.json
└── package.json

📦 包配置示例

packages/reactivity/package.json

{
  "name": "@vue/reactivity",
  "version": "1.0.0",
  "description": "响应式模块",
  "main": "index.js",
  "module": "dist/reactivity.esm.js",
  "files": [
    "index.js",
    "dist"
  ],
  "sideEffects": false,
  "buildOptions": {
    "name": "VueReactivity",
    "formats": [
      "esm-bundler",
      "esm-browser",
      "cjs",
      "global"
    ]
  }
}