skip to content
logo

Search

Monorepo 架构的落地经验

6 min read

如何通过基于 Monorepo 架构的前端工程化实践,解决组件库、脚手架和业务系统在协同开发中的依赖管理、构建效率和协作效率问题。

前端团队现状与挑战

在大型团队开发中,组件库、脚手架和业务系统是常见的核心模块,它们通常具有以下特点:

  • 组件库:提供复用的 UI 组件或工具函数,用于加速业务开发。
  • 脚手架:用于快速创建新项目或模块,标准化项目结构和配置。
  • 业务系统:作为面向最终用户的核心系统,通常依赖组件库和脚手架。

这些模块在分布式开发中存在以下问题:

  1. 依赖管理困难:组件库版本更新后,业务系统和脚手架的同步难以保证。
  2. 重复构建:不同模块需要独立构建,效率低下。
  3. 版本冲突:各模块依赖的库版本不一致,容易导致冲突。
  4. 协作复杂:跨模块调试和联调需要额外的时间成本。

引入 Monorepo 架构

解决方案概述

Monorepo 是一种将多个相关项目存储在同一个代码仓库中的管理方式,结合 pnpm、Turbo、tsup 和 Vite 等工具,可以有效解决上述问题。

主要特点:

  • 统一依赖管理:通过 pnpm 的 Workspace 功能,所有子包共享依赖,避免版本冲突。
  • 高效构建与调试:利用 turbo 按需构建,显著提升效率。
  • 模块化管理:组件库、脚手架和业务系统通过清晰的分包结构实现独立开发与协作。

架构示意

root
├── apps
│   └── business-system   # 业务系统
├── packages
│   ├── ui          # 组件库
│   └── cli         # 脚手架
├── pnpm-workspace.yaml
└── turbo.json

workspace 配置与依赖管理

pnpm workspace 配置

  1. 在项目根目录创建 pnpm-workspace.yaml 文件:
packages:
  - "packages/*"  # 组件库、工具包等共享模块
  - "apps/*"      # 业务系统
  1. 每个子包都需要独立的 package.json 文件,例如组件库的配置:
{
  "name": "@miaoma/ui",
  "version": "1.0.0",
  "main": "dist/index.js",
  "dependencies": {}
}
  1. 安装共享依赖:
pnpm install

通过以上配置,我们就建立了一个基于 pnpm workspace 的 Monorepo 工程结构。这种方式可以让所有子包共享依赖,避免重复安装,同时保持各个包的独立性。

子包依赖管理

  • 使用 PNPM 的工作空间机制添加依赖:
pnpm add @miaoma/ui --filter @miaoma/business-system
  • 子包之间的依赖通过符号链接实现本地引用,减少重复安装。

子包构建方式选择

组件库构建:Tsup

Tsup 是一个零配置、高性能的打包工具,非常适合组件库的构建需求。

  1. 安装 Tsup:
pnpm add tsup -D
  1. 在组件库子包的 package.json 中添加构建脚本:
{
    "scripts": {
        "build": "tsup src/index.ts --format esm,cjs --dts"
    }
}
  1. 执行打包
pnpm build

业务系统开发与构建:Vite

Vite 提供了极快的开发服务器和高效的构建能力,非常适合业务系统。

  1. 安装 Vite:
pnpm add vite -D
  1. 创建 vite.config.ts
import { defineConfig } from 'vite';
 
export default defineConfig({
    root: './',
    server: {
        port: 3000,
    },
    build: {
        outDir: 'dist',
    }
});
  1. 启动开发服务器:
pnpm dev

脚手架构建:按需编译

脚手架工具通常只需要将 TypeScript 代码编译为 Node.js 可执行文件。以使用 tsc 为例:

  1. 在脚手架子包的 package.json 中添加构建脚本:
{
    "scripts": {
        "build": "tsc"
    }
}
  1. 配置 tsconfig.json
{
    "compilerOptions": {
        "target": "ES2018",
        "module": "CommonJS",
        "outDir": "dist",
        "esModuleInterop": true
    },
    "include": ["src/**/*"]
}

通过以上配置,我们就完成了组件库、业务系统和脚手架的构建配置。每个子包都使用了最适合的构建工具,既保证了构建效率,又满足了不同类型项目的需求。

总结

通过引入 Monorepo 架构,我们成功解决了前端团队在组件库、脚手架和业务系统协同开发中遇到的多个挑战:

  1. 依赖管理优化

    • 通过 pnpm workspace 实现依赖共享和版本统一
    • 子包间本地引用,避免发布中间版本
    • 降低了版本冲突风险
  2. 构建效率提升

    • 基于 Tsup 的零配置组件库构建
    • Vite 驱动的高性能业务系统开发
    • 按需编译的脚手架工具链
  3. 协作效率提升

    • 统一的代码仓库,便于跨模块协作
    • 清晰的项目结构,降低维护成本
    • 简化了调试和联调流程

在实践过程中,需要注意以下几点:

  • 合理规划子包结构,避免过度拆分
  • 选择合适的构建工具,匹配不同类型项目需求
  • 建立规范的发布流程,确保版本管理的可控性

总的来说,Monorepo 架构为前端团队带来了显著的工程效率提升,是一个值得采用的技术方案。