使用 pnpm Monorepo 构建组件库和工具库

使用 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/uipackages/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 则简化了脚本执行流程。

相关推荐
han_1 天前
Vue.js 为什么要推出 Vapor Mode?
前端·javascript·vue.js
秋氘渔1 天前
Vue 3 组合式写法:侦听器 watch 和 watchEffect 的区别及使用技巧
前端·javascript·vue.js·watch·watcheffect
阿奇__1 天前
element二次封装组件套餐 搜索组件 表格组件 弹窗组件
javascript·vue.js·elementui
The_era_achievs_hero1 天前
Echarts
前端·javascript·echarts
亮子AI1 天前
【JavaScript】修改数组的正确方法
开发语言·javascript·ecmascript
可触的未来,发芽的智生1 天前
微论-自成长系统引发的NLP新生
javascript·人工智能·python·程序人生·自然语言处理
八哥程序员1 天前
你真的理解了 javascript 中的原型及原型链?
前端·javascript
隔壁的大叔1 天前
正则解决Markdown流式输出不完整图片、表格、数学公式
前端·javascript
San301 天前
深入 JavaScript 原型与面向对象:从对象字面量到类语法糖
javascript·面试·ecmascript 6
拉不动的猪1 天前
前端JS脚本放在head与body是如何影响加载的以及优化策略
前端·javascript·面试