使用 pnpm Monorepo 构建组件库和工具库
在现代前端开发中,Monorepo 是一种越来越流行的代码管理方式,它通过将多个相关包集中在一个仓库中进行管理,带来了更高效的开发体验和更简单的依赖管理。在我的项目中,我使用了 pnpm 作为包管理工具,并结合 Lerna 来运行批量脚本。本文将分享如何利用这些工具构建一个包含 UI 组件库和工具库的 Monorepo 项目。
为什么选择 pnpm 和 Lerna?
- pnpm 是一种高效的包管理工具,它通过去重存储依赖和工作空间功能,为 Monorepo 项目提供了强大的支持。
- Lerna 是一个多包管理工具,它可以很好地与 pnpm 集成,用于批量运行脚本和管理包间的依赖关系。
通过将这两者结合,可以在开发中实现依赖管理、脚本执行和构建流程的高效协作。
初始化项目
1. 创建项目结构
在项目根目录中初始化 pnpm 和 Monorepo 配置:
perl
mkdir my-monorepo
cd my-monorepo
pnpm init
pnpm install -w
接着配置 pnpm-workspace.yaml
文件,将 UI 组件库和工具库分别放在 packages/ui
和 packages/utils
目录中:
makefile
packages:
- "packages/ui"
- "packages/utils"
2. 初始化子包
为每个子包创建 package.json
文件:
UI 组件库
bash
mkdir -p packages/ui
cd packages/ui
pnpm init
配置 package.json
:
perl
{
"name": "@my-org/ui",
"version": "0.1.0",
"main": "dist/index.js",
"scripts": {
"build": "tsc"
}
}
工具库
bash
mkdir -p packages/utils
cd packages/utils
pnpm init
配置 package.json
:
perl
{
"name": "@my-org/utils",
"version": "0.1.0",
"main": "dist/index.js",
"scripts": {
"build": "tsc"
}
}
3. 配置 TypeScript
在项目根目录下创建 tsconfig.json
文件:
perl
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@my-org/ui": ["packages/ui/src"],
"@my-org/utils": ["packages/utils/src"]
}
}
}
使用 Lerna 批量运行脚本
在 Monorepo 项目中,往往需要对多个子包运行相同的脚本,例如构建、测试等。此时可以借助 Lerna 来高效地完成这些操作。
安装和初始化 Lerna
在项目根目录下安装 Lerna:
csharp
pnpm add -D lerna
配置 lerna.json
文件:
json
{
"version": "0.1.0",
"npmClient": "pnpm",
"useWorkspaces": true,
"packages": ["packages/*"]
}
批量运行脚本
构建所有子包
通过 lerna run
命令,批量运行 build
脚本:
arduino
lerna run build
Lerna 会自动检测 packages
目录下每个子包的 package.json
,并依次运行 build
脚本。
按依赖顺序执行
为了确保脚本的执行顺序正确,例如工具库需要先于 UI 库构建,可以在 nx.json
中定义依赖关系:
perl
{
"tasksRunnerOptions": {
"default": {
"runner": "@nrwl/workspace/tasks-runners/default",
"options": {
"cacheableOperations": ["build"]
}
}
},
"targetDependencies": {
"build": [
{ "target": "build", "projects": "dependencies" }
]
}
}
这样,运行 lerna run build
时,工具库会在 UI 库之前构建。
工具库与 UI 库的互相依赖
在实际开发中,工具库中的方法通常会被 UI 库使用。可以通过以下方式实现依赖管理:
添加依赖
在 UI 库中添加工具库为依赖:
sql
pnpm add @my-org/utils -r --filter @my-org/ui
示例
假设工具库中有一个格式化时间的函数:
packages/utils/src/index.ts
vbnet
export function formatDate(date: Date): string {
return date.toISOString();
}
在 UI 库中使用这个工具函数:
packages/ui/src/index.ts
javascript
import { formatDate } from "@my-org/utils";
console.log(formatDate(new Date()));
总结
通过 pnpm 和 Lerna 的结合,可以高效地管理和开发 Monorepo 项目。在实际项目中,pnpm 提供了快速的依赖管理,而 Lerna 则简化了脚本执行流程。