多端项目太乱?我是这样用 Monorepo 重构的

🚀 如何用 Monorepo 管理多端项目?一套可落地方案

一、从"架构设计"到"工程落地"

在上一篇中,我们解决了一个核心问题:

text 复制代码
多端架构应该如何设计?

我们得出的结论是:

text 复制代码
用分层架构统一逻辑(UI / modules / services)

👉 那这一篇,我们解决另一个更现实的问题:

text 复制代码
如何把这套架构真正落地?

二、为什么多端项目一定会"失控"?

当你开始同时维护 Web、小程序、App 等多个端时,传统的 Multi-repo(多仓库) 很容易演变成开发灾难:

  • 重复劳动:相同业务逻辑在多个仓库重复实现
  • 同步地狱:接口字段变更,需要手动同步多个项目
  • 维护混乱:修一个 Bug,要改多个仓库

🔥 本质问题:

text 复制代码
代码没有统一的"抽象与复用边界"

👉 所以你需要一种机制:

text 复制代码
既能共享代码,又能保持边界清晰

👉 这就是:

text 复制代码
Monorepo(单仓多包)

三、为什么多端架构必须用 Monorepo?

相比传统 Multi-repo,Monorepo 的优势非常明显:

维度 Multi-repo Monorepo
代码复用 复制 / npm 发布 本地直接引用
类型共享 手动同步 自动同步
依赖管理 各自维护 统一管理
代码变更 多仓提交 原子提交

👉 对多端项目来说,它解决了最核心的问题:

text 复制代码
让"可复用逻辑"有了统一载体

四、项目结构设计(核心)

这是 Monorepo 成败的关键。


📦 推荐结构(与架构分层一致):

text 复制代码
my-repo/
├── apps/                  # 应用层(各端独立)
│   ├── web/               # Web(Next.js / React)
│   ├── mini/              # 原生小程序
│   └── admin/             # 管理后台
│
├── packages/              # 复用能力层
│   ├── services/          # API 层(OpenAPI)
│   ├── modules/           # 业务逻辑(核心 ⭐)
│   ├── request/           # 请求适配层
│   └── shared/            # 工具函数
│
├── package.json
└── pnpm-workspace.yaml

🔥 核心设计原则:

text 复制代码
apps = 面向用户(不可复用)
packages = 面向复用(核心资产)

👉 最关键的一点:

text 复制代码
所有"可复用逻辑",必须进入 packages,而不是 apps

五、从 0 搭建 Monorepo(实操)


1️⃣ 初始化项目

bash 复制代码
mkdir my-repo && cd my-repo
pnpm init

2️⃣ 配置 workspace

创建 pnpm-workspace.yaml

yaml 复制代码
packages:
  - "apps/*"
  - "packages/*"


3️⃣ 创建目录结构

bash 复制代码
mkdir -p apps/web
mkdir -p apps/mini
mkdir -p packages/services
mkdir -p packages/modules
mkdir -p packages/request
mkdir -p packages/shared


4️⃣ 初始化子包(以 modules 为例)

bash 复制代码
cd packages/modules
pnpm init

修改 package.json

json 复制代码
{
  "name": "@repo/modules",
  "version": "1.0.0",
  "private": true,
  "main": "./index.ts",
  "types": "./index.ts"
}


5️⃣ 在应用中引用

apps/web 中执行:

bash 复制代码
pnpm add @repo/modules --workspace

然后即可直接使用:

ts 复制代码
import { useUser } from "@repo/modules"

六、依赖管理(核心原则)


🔥 原则一:依赖就近声明

text 复制代码
在哪使用,就在哪声明依赖

❌ 错误做法:

text 复制代码
所有依赖都装在根目录

👉 会导致:

text 复制代码
依赖污染 + 隐式依赖


🔥 原则二:单向依赖

text 复制代码
apps → modules → services → request

👉 严禁:

text 复制代码
modules → apps
services → modules


🔥 原则三:公共依赖再提升

例如:

bash 复制代码
pnpm add -wD typescript eslint

七、TypeScript 与构建优化


1️⃣ 类型闭环(强烈推荐)

services 中定义 API 类型:

text 复制代码
后端变更 → TS 报错 → 前端即时修复

👉 好处:

text 复制代码
把"线上错误"变成"编译错误"


2️⃣ Turborepo(进阶优化)

安装:

bash 复制代码
pnpm add turbo -wD

配置 turbo.json

json 复制代码
{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    }
  }
}

👉 带来的能力:

text 复制代码
并行构建 + 缓存加速

八、最常见的 3 个坑


❗ 1. 依赖循环(Circular Dependency)

text 复制代码
modules → shared
shared → modules ❌

👉 解决:

text 复制代码
抽象更底层包,保持单向依赖


❗ 2. 编译入口问题

部分环境(如小程序)不支持直接引用 TS 源码。


👉 解决:

text 复制代码
配置 exports / alias / 构建输出


❗ 3. 配置冗余

每个包都写 tsconfig 很麻烦。


👉 解决:

json 复制代码
// tsconfig.base.json

子包继承:

json 复制代码
{
  "extends": "../../tsconfig.base.json"
}

九、这一步完成后,你得到了什么?


✅ 工程能力提升:

text 复制代码
一次修改,多端生效
逻辑复用能力大幅提升
类型安全贯穿全链路


🔥 更重要的是:

text 复制代码
你的代码开始"结构化"

十、总结一句话

text 复制代码
Monorepo 不是工具,而是工程组织方式

🎯 结语

很多人觉得工程复杂,是因为工具太多。

但本质是:

text 复制代码
代码没有边界

👉 Monorepo 的意义是:

text 复制代码
让代码有"归属",让复杂度可控

🚀 下一篇预告

到这里,你已经完成:

text 复制代码
架构设计(第2篇)
+ 工程落地(第3篇)

👉 下一篇,我们进入最核心的一步:

text 复制代码
多端架构最难的 3 个问题(request / modules / design system)

🔥 这一篇,会是整个系列的"认知分水岭"。

相关推荐
上山打牛2 小时前
cornerstone3D基本使用
前端
阿鑫_9962 小时前
通用-Nvm基础知识
前端
xinzheng新政2 小时前
Javascript·深入学习基础知识
前端·javascript·学习
C'ᴇsᴛ.小琳 ℡2 小时前
App架构的演化
架构
程序员小郭832 小时前
MySQL分库分表策略全解析(实战版)
数据库·mysql·架构
前端付豪2 小时前
实现记忆开关
前端·后端
前端开发呀2 小时前
约定式路由的极简主义实践:一个插件搞定 React/Vue × Vite/Rspack
前端
2301_771717212 小时前
微服务架构:多模块之间通信OpenFeign
微服务·架构·asp.net
我就是马云飞2 小时前
停更5年后,我为什么重新开始写技术内容了
android·前端·程序员