探索 TinyVue 组件库系列之架构设计3:Monorepo 源码仓库管理
前端开源星球。OpenTiny TinyVue 采用了一套由 pnpm workspaces 驱动的复杂 monorepo 架构,旨在管理一个支持 Vue 2 和 Vue 3、PC 和移动平台的企业级组件库。这种结构能够在保持构建效率和依赖一致性的同时,协调多个相互依赖的包的开发。
你好,我是 Kagol,个人公众号:前端开源星球。
OpenTiny TinyVue 采用了一套由 pnpm workspaces 驱动的复杂 monorepo 架构,旨在管理一个支持 Vue 2 和 Vue 3、PC 和移动平台的企业级组件库。这种结构能够在保持构建效率和依赖一致性的同时,协调多个相互依赖的包的开发。
工作区配置
工作区的基础在根目录的 pnpm-workspace.yaml 配置中定义,该配置建立了三个主要包类别:生产包、开发示例和内部工具。此配置使 pnpm 能够通过工作区协议管理包间依赖,确保跨包的更改被正确跟踪和安装。工作区还利用 pnpm 的目录功能,为 TypeScript、Vite、Vitest 和 Playwright 等关键依赖维护统一版本,减少 monorepo 中的版本冲突。
根包管理
根目录的 package.json 强制执行严格的工具要求,要求 Node.js 18+ 和 pnpm 9.5+,并通过预安装钩子确保只使用 pnpm 进行包管理。这防止了因不同包管理器导致的安装不一致问题。根包通过集中脚本协调所有构建操作,这些脚本使用 pnpm 的过滤功能委托给特定工作区。例如,pnpm dev 和 pnpm dev2 等开发命令分别针对 Vue 3 和 Vue 2 示例环境,而构建命令则协调复杂的多包构建序列。
包架构
packages/ 目录包含按逻辑域组织的核心库架构:
| 包类别 | 用途 | 关键包 |
|---|---|---|
| 核心组件 | 组件实现 | vue, vue-runtime, vue-common |
| 逻辑层 | 无渲染/无头组件 | renderless |
| 主题 | 视觉设计系统 | theme, theme-saas |
| 工具 | 辅助函数和工具 | utils, vue-hooks, vue-directive |
| 图标 | 图标组件库 | vue-icon, vue-icon-saas, vue-icon-multicolor |
| 国际化 | 语言支持 | vue-locale |
| 设计规范 | 设计系统资源 | design (aurora, saas, smb) |
主要的 @opentiny/vue 包作为入口点,通过工作区依赖聚合了超过 200 个独立组件包。每个组件包遵循一致的结构,拥有自己的构建配置,同时依赖 @opentiny/vue-renderless 等共享包处理业务逻辑,依赖 @opentiny/vue-theme 处理样式。
无渲染架构
@opentiny/vue-renderless 包实现了无头组件模式,仅包含业务逻辑而不包含 UI 实现。这种分离允许同一逻辑在不同视觉实现和主题变体中复用。该包使用 tsup 进行高效的 TypeScript 编译,生成保留模块结构的 ESM 格式输出,以实现最优的 tree-shaking。构建配置包含通过自定义路径映射的专门类型生成,这些映射解析工作区别名和虚拟模块。
主题系统
主题架构通过独立的主题包支持多个设计系统。@opentiny/vue-theme 包使用 Gulp 提供 CSS 处理的基础实现,包括 autoprefixer、压缩和 Less 编译。@opentiny/vue-theme-saas 变体通过 Tailwind CSS 集成和自定义插件扩展了这一基础,展示了 monorepo 如何在不修改核心组件的情况下支持不同产品环境的主题定制。
开发环境
examples/ 目录为不同场景提供了隔离的开发环境:
- vue3/ - 在端口 7130 上运行的 Vue 3 开发环境,使用 Vite,通过不同的 Vite 配置模式支持标准和 SaaS 模式
- vue2/ - 在端口 7126 上的 Vue 2 开发环境,使用传统 Vue 工具链,包括 vue-template-compiler 和 Composition API polyfill 以实现功能对等
- sites/ - 官方文档站点,具有针对不同部署目标(生产、alpha、SaaS、移动端)的多种构建模式
- docs/ - 支持 PC 和移动优先模式的文档模板
两个 Vue 环境都使用工作区协议依赖直接从源代码消费包,实现无需构建步骤的实时重载开发。它们还包括使用 Playwright 进行 E2E 测试和使用 Vitest 进行单元测试的全面测试基础设施。
内部工具
internals/ 目录包含构建基础设施和自动化工具,这些工具不发布但对开发至关重要:
| 工具 | 用途 |
|---|---|
| cli | 构建协调、入口生成和组件脚手架 |
| automate | SVG 到 JS 转换、自动发布和资源管理 |
| playwright-config | 共享的 E2E 测试配置 |
| unplugin-virtual-template | 用于虚拟模板模块解析的 Vite 插件 |
| vite-plugin-template2jsx | 模板到 JSX 转换插件 |
| vue-test-utils | 具有 PC 和移动挂载模式的自定义测试工具 |
内部 CLI 作为构建协调器,处理生成组件入口点、映射依赖关系和构建运行时包等复杂操作。这些工具展示了 monorepo 如何通过针对组件库特定需求定制的自定义自动化来扩展 pnpm 的功能。
依赖管理策略
Monorepo 通过多种机制采用复杂的依赖管理:
- 工作区协议 - 内部包使用
workspace:*或workspace:~表示法,允许 pnpm 本地解析它们并在构建期间自动更新版本 - 目录依赖 - TypeScript、Vite 和 Vitest 等通用开发依赖通过目录功能管理,确保所有包的版本一致
- 覆盖 - Vue 版本等关键依赖在根级别被覆盖,以防止版本冲突并启用双 Vue 2/3 支持策略
- 补丁依赖 - 对 depcheck 和 tsup 等工具的自定义补丁解决了这些工具在特定用例中的限制
带有波浪号的工作区协议(
workspace:~)尤为重要,因为它允许 pnpm 将依赖解析到工作区版本,同时保持语义版本兼容性,确保开发构建期间的顺利更新。
构建和发布工作流
构建管道展示了 monorepo 的协调能力。构建完整组件库涉及由内部 CLI 管理的多个阶段:
- 组件映射生成识别所有组件及其依赖
- 入口点生成创建优化的导入路径
- 主题、无渲染、工具和钩子的并行包构建
- 按需加载的运行时包组装
- 分发到
packages/dist2(Vue 2)和packages/dist3(Vue 3)
发布工作流利用 pnpm 的过滤功能原子地发布多个包。pnpm pub:all 等命令协调 Vue 2、Vue 3、主题、无渲染和工具包到 npm 的顺序发布,每个包都定位到其适当的分发目录。
Monorepo 优势
这种架构带来了几个关键优势:
- 代码复用 - 无渲染层实现 Vue 2 和 Vue 3 实现之间的逻辑共享,将组件业务逻辑的重复减少约 50%
- 隔离开发 - 每个包可以独立开发、测试和版本控制,同时保持清晰的依赖关系
- 高效构建 - pnpm 的工作区感知依赖提升和构建协调最小化冗余安装和编译
- 灵活消费 - 开发者可以导入完整库、特定组件,甚至直接导入无渲染层,实现不同的使用模式
- 跨平台支持 - 通过适配器层和条件编译,单一代码库支持 Vue 2、Vue 3、PC 和移动端
联系我们
GitHub:https://github.com/opentiny/tiny-vue(欢迎 Star ⭐)
官网:https://opentiny.design/tiny-vue
个人博客:kagol.com.cn
小助手微信:opentiny-official
公众号:OpenTiny
更多推荐



所有评论(0)