本文介绍私有仓库包的管理模式 mono repo
mono repo的好处
mono repo的好处来源于这篇文章,我用自己直白点的话总结了以下几点:
- 多个内部模块可以集中管理
- 只需在根目录安装
node_modules
即可,无须所有模块都安装
例如,一个有多端的项目,而且每个端都饮用了共有的模块,我们可以把所有项目或包放到一个packages中集中管理
例如我们平时熟悉的react,babel等库的源码,都是采用mono repo进行仓库管理。
我们需要用到两个库,yarn workspace
和 lerna
, 以下的项目示例里,前者用于依赖管理,后者用于处理发布问题,在版本发布这块,使用lerna
更方便,可用于替代一部分的git的功能。
当然 lerna
也可以直接替代 yarn workspace
的功能。
yarn workspace
管理依赖
1 | mkdir common server |
package.json
配置 workspaces
package.json
,将 common, server 两个文件夹视为两个package包
1 | { |
建一个简单的目录结构如下:
1 | root |
假设在common包里安装react和react-dom,则直接执行:
1 | yarn workspace common add react react-dom --dev |
yarn workspace
的具体用法,可以看官方文档
自己写的包要相互引用的方法
我们把上面的目录结构 common 包和 server 各自添加index.js,如下:
1 | root |
packages\common\index.js
里写点简单的东西:
1 | module.exports = () => console.log('hello fr common') |
packages\server\index.js
1 | // 这里的 "common" 对应 common\package.json 里的 "name",即直接引用common作为依赖包 |
common\package.json
里,社区里的习惯性做法是加上前缀@项目名称/
,如:
1 | { |
server\package.json
运行 yarn install
,会看到以下,证明在server文件夹成功安装common文件夹作为依赖
1 | $ yarn |
返回根目录运行 ls node_modules/
可以看到多了 ‘@mono-repo-by-yarn-lerna’ / 为项目的东西
1 | $ ls node_modules/ |
运行 node server/index.js
可以看到运行的结果:
1 | $ node packages/server/index.js |
如果此时我们再在 server 文件夹里添加其他模块,例如 babel
,运行 yarn add babel
,
会发现 server 文件夹里的 node_modules
只放了 babel 的一些执行文件,其余 babel 的核心文件全部被移动到根目录里的 node_modules
,以此达到集中管理依赖的目的
Lerna
A tool for managing JavaScript projects with multiple packages.
Lerna 是希腊神话里一多头怪物,估计作者想他多头处理多个包
在我们上面项目的基础上,根目录添加lerna,yarn add -D -W lerna
,-W
表示跟在本项目的 workspace 里直接安装,即根目录
npx lerna init
packages\common\package.json
和 packages\server\package.json
均加上test命令
1 | "scripts": { |
1 | { |
如果要执行单个 package.json
里的命令,则需加上 --scope=@包名
,如
1 | "scripts": { |
如指定多个模块,只需放在{}
里,如:
1 | "scripts": { |
lerna version 发布版本
接上面,用 new-version
命令进行发版,执行的是 lerna version
。
后面的参数 convential commits
是一个用于优化 git commit 内容的库,可以添加commits标题正文注脚什么的,挺有趣,vs code 里也有同名的插件
test 脚本加上 --since
参数可以看到提交版本的历史:
1 | "scripts": { |