Lerna 多包管理工具

2,277 阅读3分钟

Lerna 多包管理工具

简介

lernaJs 是由 Babel 团队出的一个多包管理工具。因为Babel包含很多子包,以前都是放在多个仓库里的,管理比较困难,特别是有调用系统内包的时候,发布比较麻烦。所以为了能更好更快的跨包管理,babel 推出了 lernaJs,使用了monorepo 的概念,现在 React, Babel, Angular, Jest 都在使用这个工具来管理包。

Monorepo 的全称是 monolithic repository,即单体式仓库。

lerna的基础使用 Lerna 中文教程详解

案例

背景

  • 多个包有相互依赖,在本地开发的时候 npm link 本地包,不然会安装远程包
  • 多个包多个 repo 时,issues 无法统一管理
  • 多个包有公共的 pakages, 开发环境,每个包都需要安装一次
  • 多个包需要使用同一个版本号时,不便维护

什么是Lerna

多包管理工具

  • 解决 packages 之间本地开发里的相互依赖
  • 通过 git 检测改动,自动更新包版本和发布包
  • 自动生成 CHANGELOG

npm i lerna -g 安装 lerna init 初始化配置文件

文件结构

.
├── lerna.json
├── package.json
└── packages
    ├── daybyday
    │   └── package.json
    ├── gpnode
    │   └── package.json
    └── gpwebpack
        └── package.json

两种模式

  1. 统一版本号模式(Fixed):各包使用统一的版本号
    • Fixed模式(默认): 使用 lerna.json 中的 version 版本号
  2. 独立版本号模式(Independent):各包使用各自的版本号
    • Independent模式:使用各个 package 中的 version (lerna.json 中的 version 的值为 independent)
// learn.json
{
  "packages": ["packages/*"],
   // 如果是数字,就是所有子包都是这个版本。设置成‘independent’,独立管理每个包的版本
  "version": "independent""0.0.1",
  "lerna": "2.11.0"
}

lerna 会对比包的变化,自动发布需要发布的包。

Publish 的过程

  • 运行 lerna updated 来决定哪一个包需要被 publish
  • 如果有必要,将会更新 lerna.json 中的 version
  • 将所有更新过的的包中的 package.jsonversion 字段更新
  • 将所有更新过的包中的依赖更新
  • 为新版本创建一个 git committag
  • 将包 publishnpm

安装依赖

为所有子包安装依赖

// 根据根目录下的 package.json 中的  devDependencies 安装
lerna bootstrop 所有子包安装依赖
// 指定源
lerna bootstrap --registry=https://registry.npm.taobao.org

新增外部依赖包

lerna add <moduleName>  // 所有子包都添加这个依赖
lerna add <moduleName> --scope=<pkgName> // 给scope后的包添加依赖

设置依赖: 将子包设置为另一个子包的依赖

// 给pkgName2中添加pkgName1,包内的互相引用,会复制pkgName1到pkgName2中
lerna add <pkgName1> --scope=<pkgName2> 

列出所有子包

lerna ls 列出所有的子包

显示自上次发布以来有修改的包

// 列出下次发版lerna publish 要更新的包
lerna changed 
// 显示自上次relase tag以来有修改的包的差异, 执行 git diff
lerna diff

在每个包目录下执行系统命令

$ lerna exec -- <command> [..args] # runs the command in all packages
$ lerna exec -- rm -rf ./node_modules
$ lerna exec -- protractor conf.js
$ lerna exec -- npm view \$LERNA_PACKAGE_NAME
$ lerna exec -- node \$LERNA_ROOT_PATH/scripts/some-script.js

在每个包下执行 package.json 中的脚本命令

$ lerna run test
$ lerna run build

删除各个包的 node_modules

lerna clean

其它命令

lerna run < script > -- [..args] # 运行所有包里面的有这个script的命令
lerna create pkgName
lerna clean 删除所有包的node_modules目录
lerna update 更新模块
lerna publish

参考

本文使用 mdnice 排版