解决很多初学者:
只会用工具
但不知道为什么会出现这些工具
的问题。
一、前言:为什么前端越来越强调“工程化”?
很多初学者刚接触前端时,会觉得:
前端不就是写页面吗?
但真正进入企业后会发现:
企业开发的难点,很多时候并不是“功能实现”,而是“多人协作下的大型项目复杂度控制”。
例如:
- 十几个前端同时开发
- 多个业务系统同时维护
- 多端统一(Web、H5、小程序)
- 公共组件库共享
- 自动化部署
- CI/CD
- 多环境构建
- 微前端协同
此时:
代码已经不再只是代码
而是:
一整套工程体系。
所以:
工程化的本质
真正的工程化不是:
webpack配置
vite配置
而是:
用标准化、自动化、流程化的方式解决大型项目协作问题。
核心目标:
降低复杂度
提升协作效率
提升可维护性
提升自动化能力
而:
Monorepo 就是在工程复杂度不断增长后出现的企业级架构方案。
二、企业工程化架构的整体演进主线
整个企业前端架构的发展,其实是一条非常清晰的演进链路:
单项目
→ 多项目
→ 多仓库
→ 公共模块抽离
→ 工程复杂度爆炸
→ Monorepo
→ 自动化工程体系
→ 平台化研发体系
这里一定要形成一个核心认知:
所有技术方案,本质上都在解决“复杂度问题”。
包括:
| 工程化领域 | 技术 | 本质解决的问题 |
|---|---|---|
| 团队规范 | ESLint、Prettier、 commitlint、husky | 代码规范、 Git规范提交质量 |
| 自动化 | CI/CD | 自动化交付 |
| 构建体系 | vite、webpack、turbo | 构建复杂度 |
| 包管理 | pnpm、workspace | 依赖复用、本地包共享 |
| 架构设计 | monorepo | 工程统一化 |
| 发布体系 | npm publish、docker | 环境一致性 |
所以:
不要孤立学习工具,而是理解“为什么会出现这些工具”。
三、传统 Multi-repo 架构
1. 什么是 Multi-repo?
传统企业项目通常是:
一个项目 = 一个仓库
例如:
company-admin
company-web
company-h5
company-ui
company-utils
每个项目:
- 独立 Git 仓库
- 独立 package.json
- 独立 CI/CD
- 独立部署
这种模式:
叫:
Multi-repo(多仓库模式)
2. Multi-repo 的优点
在项目规模较小时:
确实非常简单。
特点:
- 项目独立
- 权限清晰
- 结构简单
- 容易理解
所以:
小团队、小项目阶段完全够用。
3. Multi-repo 的核心问题
随着项目越来越多,问题开始爆发:
(1). 项目割裂
传统:
admin-system
user-center
component-library
chart-library
tool-library
全部是独立仓库。
问题:
每个项目像“信息孤岛”
团队协作成本会越来越大。
(2).公共代码无法真正复用
例如:
request()
auth()
formatDate()
storage()
每个项目复制一份。
后果:
A项目修复bug
B项目没修
线上行为不一致。
企业里非常痛苦。
(3).版本地狱
例如:
admin 用 axios@0.27
web 用 axios@1.0
mobile 用 axios@1.6
最后:
兼容问题疯狂出现
尤其:
- React
- Vue
- TypeScript
- axios
特别容易出问题。
(4).工程规范无法统一
比如:
A项目eslint
B项目没eslint
C项目husky版本不同
于是:
团队代码风格完全不统一
新人会很崩溃。
(5).CI/CD 难统一
例如:
每个项目:
自己写docker
自己写jenkins
自己写shell
最后:
部署流程越来越混乱
四、企业为什么一定会走向 Monorepo?
真正的问题本质不是:
仓库太多
而是:
工程体系无法统一。
所以企业开始意识到:
不能再“各玩各的”
于是:
进入公共能力抽离阶段
五、公共能力抽离(工程化开始萌芽)
企业开始发现,很多东西本质上是 “基础设施” 。
例如:
| 公共能力 | 是否应复用 |
|---|---|
| UI组件库 | 是 |
| 工具函数库 | 是 |
| 请求SDK | 是 |
| 权限模块 | 是 |
| 埋点SDK | 是 |
| 图表模块 | 是 |
于是开始:
抽离公共npm包
例如:
company-ui
company-utils
company-request
company-auth
六、公共 npm 包阶段的新问题
虽然实现了代码复用,但新的复杂度又出现了。
(1)npm 发版地狱
改一个组件:
publish
安装
联调
重新测试
流程很长。
(2)版本割裂
例如:
A系统 ui@1.0
B系统 ui@2.0
最终:
同一个组件行为不一致
(3)本地联调困难
因为:
本地源码无法直接共享
七、Monorepo 架构正式出现
于是企业进入Monorepo 阶段
1. 什么是 Monorepo?
Monorepo:
Mono = 单一
Repo = 仓库
即:
所有项目统一到一个仓库中管理。
例如:
universal-chat-human/
├── apps/ # 业务应用层
│ ├── admin-web
│ ├── chat-web
│ ├── mobile-h5
│ └── example
│
├── packages/ # 基础能力层
│ ├── shared # 公共工具
│ ├── ui # UI组件库
│ ├── chat-logic # 聊天逻辑
│ ├── brain-core # AI核心
│ ├── workflow-engine # 工作流
│ ├── request-core # 请求库
│ ├── auth-core # 权限模块
│ └── config # 公共配置
│
├── scripts/ # 自动化脚本
│
├── configs/ # eslint/tsconfig等
│
├── docker/ # docker配置
│
├── .github/ # CI/CD
│
├── turbo.json
├── pnpm-workspace.yaml
├── package.json
└── README.md
2. Monorepo 的核心思想
Monorepo 本质不是:
代码放一起
而是:
工程体系统一化。
包括:
- 统一依赖
- 统一规范
- 统一构建
- 统一发布
- 统一CI/CD
- 统一自动化流程
八、Monorepo 的核心分层思想
企业级 Monorepo:
本质是:
业务层 + 基础能力层 分离
1. apps:业务应用层
例如:
admin-web
chat-web
mobile-h5
这些:
面向用户。
2. packages:基础能力层
例如:
ui
utils
request
auth
shared
这些:
面向团队复用。
这是企业架构非常重要的思想。
九、为什么 pnpm 是 Monorepo 最佳搭档?
1. npm/yarn 的问题
传统:
每个项目重复安装依赖
例如:
react
axios
lodash
会被复制很多份。
问题:
- node_modules 巨大
- 安装慢
- 磁盘占用高
2. pnpm 的核心思想
pnpm采用:
中心化存储 + 硬链接
(1)中心化缓存
pnpm 会将依赖包内容统一存储到全局 Store 中,
相同版本的依赖不会重复下载与重复存储。
(2)链接机制
内容寻址存储 + 硬链接 + 符号链接(软硬链接)
pnpm 会先将依赖统一存储到全局 store 中,再通过硬链接与符号链接的方式,将依赖映射到项目的 node_modules 中。
因此多个项目之间可以共享同一份依赖内容,而不需要重复复制依赖文件。
项目中的:
node_modules/react
本质只是链接。
真正文件在:
pnpm store
pnpm 真正最核心的思想不是“集中存储”,而是“基于内容寻址的全局依赖复用”。
(3)workspace 原生支持
例如:
packages:
- apps/*
- packages/*
pnpm会自动识别:
本地包依赖关系
例如:
"@company/ui": "workspace:*"
意味着:
表示当前依赖优先使用本地 workspace 包,而不是从 npm 仓库下载。
这样可以实现本地包之间的联调与共享,大幅提升开发效率。
这是:
Monorepo 的核心灵魂。
十、workspace 真正解决了什么?
workspace 机制允许本地包之间直接建立链接关系, 从而避免频繁 npm publish, 大幅提升本地联调效率。
以前:
修改组件库
→ publish
→ 业务项目重新安装
现在:
改完直接联调
因为:
共享的是源码
这是企业生产力巨大提升。
十一、Turbo 为什么会出现?
Monorepo 后仓库越来越大。
例如:
100+ packages
此时:
构建复杂度开始爆炸。
于是:
Turbo 出现。
十二、Turbo 的核心能力
Turbo本质是:
任务调度系统。
1. 增量构建
例如:
只修改 ui
则:
只构建 ui 相关项目
2. 构建缓存
代码没变:
直接读取缓存
不重新构建。
3. 依赖任务排序
例如:
utils → ui → web
Turbo 自动按依赖顺序构建。
十三、Monorepo 真正困难的地方
真正困难不是搭建,而是:
依赖关系管理。
1. 循环依赖问题
例如:
ui → utils
utils → shared
shared → ui
会导致:
- 构建死循环
- 类型丢失
- 热更新异常
2. 企业中的依赖分层思想
企业通常会这样:
shared
↑
utils
↑
ui
↑
business
原则:
下层不能依赖上层
这叫:
分层架构设计。
十四、企业级构建工具体系
1. Vite
适合:
业务系统
特点:
- 启动快
- HMR快
- 开发体验好
2. tsup
适合:
SDK、工具库
特点:
- 极简
- 基于esbuild
- 构建速度快
3. Rollup
适合:
组件库
因为:
Tree Shaking优秀
4. Webpack
适合:
超大型历史项目
特点:
- 可配置性极强
- 插件生态完善
十五、企业级工程规范体系
很多人误以为:
工程化 = 打包
其实:
规范化才是核心。
1. ESLint
解决:
代码规范问题
2. Prettier
解决:
代码格式统一
3. Husky
解决:
提交前自动校验
4. Commitlint
统一:
Git Commit规范
例如:
feat: 新增登录模块
fix: 修复权限问题
十六、scripts 为什么是工程核心?
大型企业不会把所有逻辑:
写在shell里
而会有企业级脚本体系:
scripts/
统一管理:
构建脚本
发布脚本
生成脚本
自动化脚本
例如:
scripts/
├── build.ts
├── release.ts
├── deploy.ts
└── gen-module.ts
作用:
标准化流程入口。
十七、CI/CD 自动化体系
Monorepo 一定伴随 CI/CD 自动化流水线,因为:
仓库太大
人工操作不现实。
典型流程:
git push
↓
GitHub Actions
↓
Turbo增量构建
↓
自动测试
↓
Docker打包
↓
自动部署
十八、Docker 为什么重要?
因为:
开发环境
测试环境
生产环境
必须一致。
否则:
本地正常
线上报错
Docker本质:
环境标准化。
十九、企业级发布体系
1. SDK/组件库
通常:
npm publish
发布到:
- npm
- 私有npm仓库
2. 业务系统
通常:
Docker镜像部署
例如:
docker build
docker push
二十、Monorepo 最终会演进到什么?
真正大型企业最终会进入平台化研发体系:
1. 自动化平台
自动:
- 创建项目
- 创建模块
- 创建页面
2. 发布平台
自动:
- 打包
- 发布
- 回滚
3. 可视化CI平台
统一:
- 流水线
- 权限
- 日志
4. 低代码平台
进一步减少:
重复开发
二十一、整个工程化体系的最终核心思想
现在你应该形成一个非常重要的认知,整个企业工程化体系的发展主线其实是:
业务规模增长
→ 工程复杂度提升
→ 工程体系升级
→ 自动化增强
→ 平台化建设
所以:
所有技术本质都在解决“复杂度问题”。
二十二、正确的学习路线(非常重要)
第一阶段:基础能力
必须真正掌握:
- Git
- npm/pnpm
- package.json
- node_modules
- Vite
- TypeScript
第二阶段:小型 Monorepo 实践
亲手搭建:
apps/
packages/
体验:
- workspace
- 包共享
- turbo构建
第三阶段:规范体系
加入:
- eslint
- prettier
- husky
- commitlint
第四阶段:自动化体系
学习:
- GitHub Actions
- Docker
- CI/CD
第五阶段:架构设计思想
真正理解:
为什么企业会这样设计
而不是:
只会搭脚手架
二十三、面试中的高质量表达
在过往项目中,我参与并主导了前端工程化架构升级工作,整体基于 pnpm workspace + monorepo 的方式统一管理团队项目。
早期项目采用传统 multi-repo 模式,组件库、业务系统、工具库之间相互割裂,存在依赖版本不统一、公共代码重复、CI流程不一致等问题。随着项目规模扩大,协作成本逐渐增高,因此后续推动了 monorepo 架构演进。
在具体实践中,我们通过 pnpm workspace 统一子包管理,基于 packages + apps 的结构拆分基础能力层与业务应用层,例如将 UI组件库、工具库、请求库、权限模块等抽离为独立 packages,实现跨业务共享。
构建体系方面,我们引入 Turbo 进行任务调度与增量构建,通过缓存机制优化 CI 构建耗时,同时对子包依赖关系进行分层设计,避免循环依赖问题。
工程规范方面,统一了 ESLint、Prettier、Commitlint、Husky 等规范化工具,并结合 GitHub Actions 实现自动化测试、构建与部署。
在构建工具选型上,业务系统主要采用 Vite,基础 SDK 与工具库采用 tsup 进行构建,组件库部分结合 Rollup 做 Tree Shaking 优化。
整体上,这套 monorepo 工程体系有效提升了代码复用率、团队协作效率以及自动化交付能力。