Lerna入门:从零构建TypeScript Monorepo并发布至NPM
本文详细介绍如何使用Lerna从零搭建TypeScript Monorepo项目。涵盖Lerna的fixed与independent两种版本管理模式,演示环境配置、包创建、TypeScript编译集成以及最终发布到NPM仓库的完整流程,帮助开发者高效管理多包代码库。
Lerna 简介
本文面向Lerna初学者,将演示如何从零构建一个TypeScript项目,并利用Lerna将其中包含的多个子包发布至NPM仓库。
Lerna是一款基于Git和Npm的多包仓库管理工具,专为管理包含多个JavaScript包的复杂项目而设计。它主要提供两种工作模式:fixed(固定版本)模式和independent(独立版本)模式。
Fixed 模式
Fixed 模式是Lerna的默认行为。在此模式下,所有包的统一版本号保存在项目根目录的 lerna.json 文件的 version 字段中。执行 lerna publish 命令时,Lerna会检查自上次发布以来是否有模块发生更新。仅当模块内容有变更时,该模块才会以新版本发布;未变更的模块则保持原样。需要注意的是,如果当前主版本号为 0 或主版本号发生更新,所有模块无论是否更新都将被强制发布。在 Fixed 模式下,开发者只需为待发布的模块指定一次版本号,所有被发布的模块将共享相同的版本号。
Independent 模式
将 lerna.json 文件中的 version 字段设置为 independent,即可启用 Independent 模式。在此模式下,Lerna 允许开发者为每个待发布的模块单独指定和管理版本号,实现版本控制的独立性。
前置准备
全局安装 Lerna
npm install -g lerna
NPM 账户
本示例旨在演示如何将包发布至NPM公共仓库,因此需要先在 www.npmjs.com 注册并创建一个NPM账户。
Git 环境
Lerna 的功能深度依赖 Git,包括检测文件变更、自动发布流程、版本号管理以及根据 Commit Message 自动生成 Changelog。因此,必须确保系统中已安装 Git。
项目初始化
本演示项目包含两个子包,其目录结构如下所示:

创建一个名为 leran-ts-demo 的文件夹,并在该目录下执行初始化命令。
lerna init
命令执行完毕后,leran-demo 文件夹中将生成以下初始文件结构:
- /packages
- lerna.json
- package.json
/packages 目录初始为空,后续所有由 Lerna 管理的子包都将存放于此文件夹中。
lerna.json 是 Lerna 的核心配置文件,其初始内容如下:
{
"packages": [
"packages/*"
],
"version": "0.0.0"
}
由于 Lerna 不会自动创建 .gitignore 文件,我们需要手动创建该文件,内容如下:
node_modules/
lerna-debug.log
npm-debug.log
packages/*/lib
.idea
创建子包
在本示例中,我们需要管理的两个子包分别为 math-demo 和 request-demo。通过 lerna create 命令来创建这些包。在仓库根目录执行 lerna create math-demo,结果如下:

重复上述步骤创建 request-demo。创建完成后,目录结构更新如下:

由于项目使用 TypeScript 编写源代码,我们需要安装 TypeScript。在仓库根目录运行 lerna add 命令,将 typescript 添加到所有包的依赖中。
lerna add typescript --dev
鉴于所有子包均使用 TypeScript,我们在仓库根目录创建一个公共的 tsconfig.json 文件,内容如下:
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"lib": [
"es6"
]
},
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
创建好公共 tsconfig.json 后,还需为每个子包创建独立的 tsconfig.json 文件,配置如下:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./lib"
},
"include": [
"./src"
]
}
为每个子包添加 tsconfig.json 后,我们还为每个包创建了 src 目录以存放 TypeScript 源文件。为了使 TS 文件能编译为 JS,我们在每个包的 package.json 中定义了 tsc 脚本,结果如下:

在仓库根目录下执行以下命令:
lerna run tsc
上述命令将并行运行所有子包中的 tsc 脚本。

若编译顺利,TS 文件将从 src 文件夹编译输出至每个子包的 lib 文件夹中。请检查各子包 package.json 中的 directories, files, typings, publishConfig 和 main 属性:

这些配置至关重要,它们决定了哪些文件会被推送到 NPM,并指定了 NPM 包的入口文件。
代码托管至 GitHub
在 GitHub 上创建一个新的代码仓库,并将本地仓库与远程仓库进行关联。
发布至 NPM
假设已拥有 NPM 账户,接下来只需在终端中登录 NPM 即可。

现在项目结构和构建脚本已准备就绪,我们将 publish 命令定义到仓库根目录的 package.json 中。
{
"scripts": {
"publish": "lerna run tsc && lerna publish"
}
}
在仓库根目录执行以下命令:
npm run publish
Lerna 将引导我们完成发布流程。在此过程中,我们需要指定包的版本号,并将 Tag 推送到 GitHub。若一切顺利,最终将看到提示消息:lerna success 发布了 2 个包。
验证发布结果
在命令行中执行以下命令:
npm info request-demo
npm info math-demo
此时将显示相关 NPM 包的详细信息,以确认发布成功。
总结
本示例演示使用的是 Lerna 的 fixed 模式,读者可以尝试切换至 independent 模式,以体验两者在版本管理上的差异。
以上即为 Lerna 入门之管理 TypeScript Monorepo 教程的详细内容,更多关于 Lerna 管理 TypeScript Monorepo 的资料请关注本站其他相关文章!
JS处理含Emoji或中文的字符串转数组乱码问题
2026-11-05 16:12:28
JS怎么使用展开运算符合并对象
2026-11-05 14:42:18
ES6+环境下判断JS对象为空的简洁写法
2026-11-05 12:12:23
怎么通过replacer函数自定义JS中JSON的格式化输出
2026-11-05 11:19:44
JS正则表达式基础:字面量与RegExp构造函数的区别及常用元字符
2026-11-05 11:16:58








