背景
最近平台启动了物料市场技术项目,目的是通过提供丰富可复用物料、一体化物料解决方案、全链路研发来实现对研发体验和研发效率的提升。在设计公共组件架构时平台采用了多包架构(Monorepo),一套灵活的组件研发体系,并且天然支持按需使用。
什么是 Monorepo
monorepo 是一种将多个项目代码存储在一个仓库里的软件开发策略,这种方式在一个项目仓库(repo)中管理多个模块/包(package)。很多出名开源的项目都是采纳的 monorepo 的组织形式,比如 Babel,React ,Jest, create-react-app, react-router 、 npm@7 也带来一流的 monorepo 支持等等。
monorepo 的优劣
monorepo 的优势
- 代码重用将变得非常容易
- 依赖管理将变得非常简单
- 代码重构将变得非常便捷
monorepo 的劣势
- 项目粒度的权限管理变得非常复杂(既是优点也是缺点)
- 学习成本变高
- 库体积超大,目录结构复杂度上升
基于两者的优缺点,结合我们当前组件库的特点:
● 每个包之间是有相关依赖的。
● 统一的构建工具,统一发版。
● 对版本的说明要求较高
所以我们推荐采用 Monorepo 对组件库进行管理,目前最常见的 Monorepo 解决方案是 Lerna 和 Yarn 的 workspaces 特性。我们采用 Yarn 官方推荐的做法,用 Yarn 来处理依赖问题,用 Lerna 来处理发布问题。
lerna
A tool for managing JavaScript projects with multiple packages. Lerna is a tool that optimizes the workflow around managing multi-package repositories with git and npm.
基于上文我们可以知道 lerna 是最出名的 monorepo 的管理工具,也是当前项目采用的方案
通过 lerna 创建的项目结构
1 | - packages(目录) |
lerna.json 文件,默认内容为:
1 | { |
我们根据需求修改之后
1 | { |
- npmClient
我们显示声明了我们的包客户端为 yarn。 - useWorkspaces
让 Lerna 追踪我们 workspaces 设置的目录。 - version
independent 将每个子项目的版本号看作是相互独立的。
Verdaccio
一个 npm 包本地发布工具,使用 Verdaccio 可以在本地创建一个 npm 仓库作为代理用来测试 lerna。
1 | npm install --global verdaccio |
在您的项目根目录创建 .npmrc 文件
1 | registry="http://localhost:4873/" |
每当您执行 lerna publish 时,子项目所构建成的 package 将会发布在本地 npm 仓库中,而当您执行 lerna bootstrap 时,Verdaccio 将会放行,让您成功从远程 npm 仓库中拉取相应的代码。
lerna 常用命令
- lerna init
初始化 lerna 项目 - lerna create
创建一个新的由 lerna 管理的包。 - lerna add axios
增加模块包到最外层的公共 node_modules 中 - lerna add A –scope=B
增加模块包到 packages 中指定项目,例如将 A 模块增加到 B 项目中 - lerna list
显示所有的安装的包 - lerna clean
从所有包中删除 node_modules 目录 - lerna publish
在当前项目中发布包 publish 不会发布 package.json 中 private 为 true 的包 - lerna bootstrap
lerna 提供了可以将子项目的依赖包提升到最顶层的方式 ,我们可以执行 lerna clean 先删除每个子项目的 node_modules , 然后执行命令 lerna bootstrop –hoist。
基于上面的命令我们的脚手架 duwork 也同步实现
物料按照 Monorepo 的方式组织代码结构
包的结构
1 | - packages |
开发流程
1 | 创建 |
正常的开发流程是每个人新建一个 git branch,通过代码审核之后进行合并。从上面可以看到整套流程在 monorepo 架构下变得非常清晰。
总结
通过本文我们介绍了 monorepo,以及最佳实践,monorepo 给我们带来的收益是非常可观的,可能您的场景并不试用 monorepo,所以说脱离实际情况谈最优解都是不切实际的想法,一个模式的提出必定面对解决一个问题,但是即使您的场景并不试用 monorepo,还是希望工具和思想也可以运用到工作之中。