lerna 从0到1

2021-06-29 11:17:45 浏览数 (1)

简介

Lerna 是一种工具,针对 使用 git 和 npm 管理多软件包代码仓库的工作流程进行优化。 多包管理器

背景

当前手上需要同时维护几个npm工具包,有些包与包之间存在依赖管理。 经常更新某个底层包后,需要同时更新上层包。 维护的心智负担着实不小。所以希望通过 lerna 多包管理器,提高npm包的维护效率。

  • lerna 4.0.0

DEMO 目录

  • root/
    • lerna.json lerna 配置
    • package.json
    • packages/ npm包集合
      • pkg-ts npm 子包
      • pkg-es6

安装

代码语言:javascript复制
npm i -g lerna

初始化

首先进入根目录, 调用初始化命令init 。 lerna 将为我们生成基础的项目目录和配置.

代码语言:javascript复制
lerna init

image.png

模式

lerna 对包的有两种处理模式, 固定模式 独立模式

  • 固定模式

管理下的所有包使用 lerna.json 的统一版本线。 例如我们存在包 A: v1.0.0 , b: v2.0.0 lerna.json v1.0.0。 发布新版本时,更新版本为v1.1.0。 A , B , lerna.json 的版本号都将统一为 v1.1.0。 这里模式适合,包集合统一依赖,包集合作为整体工具来使用

  • 独立模式

与固定模式相反, 独立模式允许各个包独立管理自己的版本。 此时 lerna.json 中的 version 字段值为 "independent"

  • 模式设置
代码语言:javascript复制
// 方式一 初始化时, 添加 -i 或 --independent 参数
lerna init -i
代码语言:javascript复制
// 方式二 直接配置lerna.json
// lerna.json
{
  ...
  "version": "independent"
}

配置文件

lerna.json 配置文件中,我们设置详细的自定义配置。

代码语言:javascript复制
{
  // 统一版本号,   
  "version": "0.0.0",
  // 包管理工具类型, npm, yarn, cnpm, 之后的命令将使用该配置, 例如依赖安装
  "npmClient": "npm",
  // 包目录, 可以指定多个目录或目录匹配规则。
  "packages": [
      "packages/*" // 需要管理的包都放在 packages/ 目录下 
   ],
  // 是否开启"工作空间"
  "useWorkspaces": false,
  // 命令行配置
  // 调用命令行时,将合并该配置内容执行相关命名
  // 命令可配置项于命令行一一对应
  "command": {
    // 命令名称
    "bootstrap": {
      // 命令参数名: 参数值 
      "ignore": "component-*",
      // 等价于命令 lerna bootstrap --ignore=component-*
    }
    ...
  }
}

配置文件可以认为保存我们经常使用的命令操作配置,简化使用。命令使用及配置查看 基础命令, 进阶命令

基础命令

学lerna 主要学习的是lerna 常用管理命令, 例如 依赖安装,版本管理,发包等。

init 初始化

用来初始化lerna 项目

代码语言:javascript复制
lerna init

参数:

  • -i or --independent 使用独立模式, 默认固定模式
  • --exact 使用固定模式

create 创建包

将在包集合目录下,新建包基础目录结构 lerna create [名称] [集合目录]

代码语言:javascript复制
lerna create utils

参数:

  • name 名称
  • loc 包集合目录, 单一包集合时为可选。
代码语言:javascript复制
// leran.json 
{
  "packages": [
    // 存在多个包集合
    "source/*", 
     "utils/*",
  ]
}

// shell // 在指定包集合中新增day包 lerna create day utils

  • -- yes 跳过交互配置
代码语言:javascript复制
learna create day --yes
  • --bin 是否为可执行包
  • --description 包描述
  • --dependencies 依赖列表
  • --es-module 初始化为ES6 模块
  • --homepage 包首页地址
  • --keywords npm 查询关键子列表
  • --license 开源许可
  • --private 私有包
  • --registry npm源
  • --tag 标签
代码语言:javascript复制
lerna create day --description=一段描述

boostrap 安装依赖

为所有包安装依赖, 并链接相关的本地依赖包。

代码语言:javascript复制
lerna boostrap

参数:

  • --ignore 忽略

安装时,跳过某些包的依赖安装。lerna bootstrap --ignore [包命|包命匹配规则] 这里的包命指的是 package.json 中 name 属性定义的包名

代码语言:javascript复制
// 不为 pkg-ts 安装依赖
lerna bootstrap --ignore pkg-ts
// 不为 以 pkg- 开头的包安装依赖
lerna bootstrap --ignore pkg-*
  • --hoist 提升

正常情况下, 依赖安装在对应的包目录下。有时候多个包有相同的依赖或我们希望依赖相同的包实例, 可以将依赖包安装到根目录。

代码语言:javascript复制
lerna bootstrap --hoist
  • --nohoist

依赖提升时,忽略部分包, --nohoist=[依赖包名 | 依赖包命匹配规则]

代码语言:javascript复制
// 依赖提升,但不提升babe依赖
lerna bootstrap --hoist --nohoist=babel-*
  • --strict 严格模式

相同依赖包的版本不兼容时,将报错并终止安装

代码语言:javascript复制
lerna bootstrap --hoist --strict
  • --ignore-scripts

忽略生命周期钩子的调用

代码语言:javascript复制
lerna bootstrap --ignore-scripts
  • --npm-client

包管理工具类型

// 使用 yarn 安装依赖 lerna bootstrap --npm-client=yarn

  • --use-workspaces

开启workspaces

代码语言:javascript复制
lerna bootstrap --use-workspaces

同时需要在根目录package.json 配置 workspaces

代码语言:javascript复制
// root/package.json
{
  "workspaces": ["packages/*"]
}
  • --force-local

始终使用本地依赖,无论版本是否匹配

代码语言:javascript复制
lerna bootstrap --force-local
  • --no-ci / --ci

npm ci 开启or关闭

代码语言:javascript复制
lerna bootstrap --no-ci
or
lerna bootstrap --ci

clean

清理所有依赖, 删除所有包内node_modules

代码语言:javascript复制
lerna clean

参数:

  • --yes

不做确认提示

代码语言:javascript复制
lerna clean --yes

list

显示包列表

代码语言:javascript复制
lerna list
// or 
lerna ls

参数

  • --json

以json的形式显示

  • --all | -a

显示所有包,包括私有包

  • --long | -l

显示扩展信息

  • --parseable

显示包路径列表

  • --toposort

按照依赖关系显示

  • --graph

按照依赖关系以json形式显示

进阶命令

publish

发包

代码语言:javascript复制
learn publish

参数:

  • form-git

根据 git commit 的 annotaed tag 确定包版本,进行发包

代码语言:javascript复制
lerna publish from-git
  • from-package

根据 package.json 的版本,进行发包

代码语言:javascript复制
lerna publish from-package
  • --canary

根据上次版本计算出新的版本号,进行发包。 不会进入版本交互模式中

代码语言:javascript复制
lerna publish --canary
  • --contents <dir>

指定发布的包内容, 类似 package.json 的 files 属性

代码语言:javascript复制
lern publish --contents lib
  • --dist -tag

新增 dist-tag 标签

代码语言:javascript复制
lerna publish --dist-tag next
  • --no-verify-access

禁止npm权限校验

代码语言:javascript复制
lerna publish --no-verify-access
  • --preid

为--canary 提供指定的发布标识符

代码语言:javascript复制
lerna publish --canary
# uses the next semantic prerelease version, e.g.
# 1.0.0 => 1.0.1-alpha.0


lerna publish --canary --preid next
# uses the next semantic prerelease version with a specific prerelease identifier, e.g.
# 1.0.0 => 1.0.1-next.0
  • --pre-dist-tag

--dist-tag 的预发布版本

代码语言:javascript复制
lerna publish --pre-dist-tag next
  • --registry

使用指定源发布

代码语言:javascript复制
lerna publish --registry https://cnpmjs.org
  • --tag-version-prefix

自定义版本前缀, 默认: v

代码语言:javascript复制
# locally
lerna version --tag-version-prefix=''


# on ci
lerna publish from-git --tag-version-prefix=''
  • --ignore-scripts

禁用生命周期钩子脚本

代码语言:javascript复制
lerna publish --ignory-scripts
  • --yes

跳过确认

代码语言:javascript复制
lerna publish --canary --yes

add

安装包, 类似 npm i package,

代码语言:javascript复制
// 为所有包安装 dayjs 依赖
lerna add dayjs

参数:

  • --scope

限制安装范围

代码语言:javascript复制
// 只为包 pkg-1 安装依赖 dayjs
lerna add dayjs --scope=pkg-1
// 等价于 cd pkg-1/ && npm i dayjs
  • --dev

开发依赖

代码语言:javascript复制
lerna add rollup --dev
  • --exact
代码语言:javascript复制
使用精确版本,而不是版本范围。
例如 默认添加版本号: ^1.0.1, 精确版本: 1.0.1

lerna add --exact
  • --peer

添加到 peerDependencies 中

代码语言:javascript复制
lerna add vue --peer
  • --registry <url>

使用指定源安装

代码语言:javascript复制
lerna add vue --registry http://r.npm.taobao.org/
  • --no-bootstrap

跳过 bootstrap

代码语言:javascript复制
lerna add rollup 

version

创建新的包版本 执行流程:

    1. 标识自上次标记发布以来已更新的包。
    1. 新版本的提示。
    1. 修改包元数据,执行各个包内的生命周期钩子。
    1. 提交修改和标签。
    1. 推送到 git 远端分支。
代码语言:javascript复制
lerna version

参数

  • bump

版本更新方式

  • major 主版本
  • mior 副版本
  • patch 修复版本
  • premajor 预发布主版本
  • preminor 预发布副版本
  • prepatch 预发布修复版本
  • prerelease 预发布版

参数: @lerna/version(翻译

run

指定package.json 脚本命令

代码语言:javascript复制
lerna run build

参数:

  • --stream

显示子进程输出

代码语言:javascript复制
lerna run <命令> --stream
  • --parallel

显示子进程输出, 忽略排序

代码语言:javascript复制
lerna run <命令> --parallel
  • --no-bail

禁止非零退出

代码语言:javascript复制
lerna run --no-bail test
  • --no-prefix

禁止包前缀

代码语言:javascript复制
lerna run --no-prefix
  • --profile

生成性能分析文件

代码语言:javascript复制
lerna run build --profile
  • --profile-localtion <path>

生成并保存性能分析文件

代码语言:javascript复制
lerna run build --profile-localtion

exec

在每个包中,执行命令行, run 命令的底层命令

代码语言:javascript复制
lerna exec -- echo xx > logs.text
  • --scope

限制命令作用范围

代码语言:javascript复制
lerna exec --scope <包名> -- cd ./src
  • --stream

显示命令输出, 带包前缀

代码语言:javascript复制
lerna exec --scope localPackage -- ls 
  • --parallel

显示命令输出, 忽略排序

代码语言:javascript复制
lerna exec --parallel localPageck -- ls
  • --no-bail

禁止非零退出

代码语言:javascript复制
lerna exec --nobail ...
  • --no-prefix

禁止包前缀

代码语言:javascript复制
lerna exec --no-prefix
  • --profile

生成性能分析文件

代码语言:javascript复制
lerna exec --profile
  • --profile-localtion <location>

生成并保存性能分析文件

代码语言:javascript复制
lerna exec --profile --profile-location=logs/profile/ -- <command>

import

导入外部独立包, 例如我们之前为使用lerna 管理的独立npm包, 导入到lerna项目包集合后, 可以使用改目录导入相关 git 记录等

代码语言:javascript复制
lerna import <包地址>

参数:

  • --faltten
代码语言:javascript复制
lerna import ./package --flatten
  • --dest

根据 lerna.json 指定导入的目录

代码语言:javascript复制
// lerna.json
{
  "packages": [
    "pakcages/*",
    "utils/*"
  ]
}
// 执行导入
lerna import ../out-pkg --dest=utils
// out-pkg 将被导入utils目录下
  • --preserve-commit

保留原git 提交者信息以及时间

代码语言:javascript复制
lerna import ../out-pkg --preserve-commit

changed

显示下次将发布的包列表, 一般是包版本发生变化

代码语言:javascript复制
lerna changed

命令参数于 list 命令相同。

  • --json
  • --ndjson
  • -a --all
  • -l --long
  • -p --parseable
  • --toposort
  • --graph

diff

显示包修改内容, 类似 git diff

代码语言:javascript复制
lerna diff

info

显示环境信息

代码语言:javascript复制
lerna info

问题

  • 发布时git add 失败

这里我在.gitignore 中忽略了, 版本锁文件。 package-lock.json。 造成git add 发生冲突

参考文档

  • 深入 lerna 发包机制 —— lerna publish-技术圈
  • @lerna/version(翻译)
  • @lerna/publish(翻译)
  • 深入 lerna 发包机制 —— lerna version

0 人点赞