什么是monorepo和pnpm workspace

292 阅读4分钟

什么是monorepo和pnpm workspace

monorepo

monorepo 是一种项目代码管理策略,其中所有项目和依赖项都存储在单个代码库中。与他相对立的是多项目代码管理策略 multirepo,即每个项目都有自己的代码库。

monorepo 的优点

  1. 代码共享:可以减少重复代码,提高代码复用性。团队成员可以在同一仓库中工作,减少了跨多个仓库协调的需求。开发者可以更容易地访问其他人的代码,促进知识共享和技术交流。。
  2. 依赖管理:所有相关项目都在同一个仓库内,这使得它们之间的依赖关系更容易管理和维护。例如,当一个内部库被更新时,所有依赖它的项目可以立即获得更新,并且可以通过单一命令来处理整个仓库的依赖安装。
  3. 配置管理:由于所有的代码都在一个地方,因此就像测试工具,prettier,eslint 等配置可以统一管理,不需要每个项目都去配置,保证了统一性和标准化。
  4. 降低复杂度:与 multirepo 相比,当一个依赖项存在 bug,则需要去这个依赖项上进行修改,然后发布 npm 包,然后切到所有的项目上去更新最新的包,才可以。而 monorepo 则可以在一个地方进行修改,然后依赖它的项目使用的是 workspace 的依赖,都会自动更新。

monorepo 的缺点

  1. 代码库管理复杂:随着项目越来越多,权限管理可能变得更加复杂,特别是如果想要对不同的子项目实施细粒度控制的话。
  2. 代码库体积变大:随着项目越来越多,代码库体积会变大。

什么是pnpm workspace

pnpm workspace 是 pnpm 的一个功能,用于管理多个包。它允许你在 Monorepo(单体仓库)环境中更高效地管理和共享依赖。通过 pnpm workspace,你可以定义多个包或项目,并将它们作为一个整体来处理依赖关系、安装和构建等操作。

pnpm workspace 的优点

  1. 依赖管理:pnpm workspace 可以自动管理多个包之间的依赖关系,确保所有包都使用相同的依赖版本。
  2. 安装和构建:通过 pnpm workspace,你可以一次性安装和构建所有包,而无需手动处理每个包的依赖关系。
  3. 代码共享:pnpm workspace 可以自动管理包的代码共享,确保所有包都使用相同的代码。

pnpm workspace 的使用

创建 workspace
  1. 如果没有安装 pnpm,则需要先安装 pnpm。
npm i -g pnpm

可以通过查看版本号来判断是否安装成功

pnpm -v
  1. 创建 package.json 文件
pnpm init
  1. 配置 workspace

新建 pnpm-workspace.yaml 文件

packages:
  - 'packages/*'
  1. 创建 packages 文件夹

  2. 创建两个项目后,简易的目录结构如下

├── packages
│   ├── packages1
│   │   ├── src
│   │   └── package.json
│   │   └── index.js // 对外暴露
│   ├── packages2
│   │   ├── src
│   │   ├── package.json
│   │   └── index.js // 对外暴露
├── package.json //全局第三方公用包管理,如 axios
├── pnpm-lock.yaml
└── pnpm-workspace.yaml // 配置 项目+依赖的公用模块

这个时候如果我在 packages1 中想使用 packages2 中的功能函数或者封装的组件,则需要在 packages1 中安装 packages2 的依赖。

pnpm install package2 --workspace

安装成功后,在 package.json 中会自动添加

// package.json
"包2名称": "workspace:^"

这个时候,在 packages1 中就可以使用 packages2 中的功能函数或者封装的组件了。

这个一般使用在 npm 包的开放中,使用 pnpm workspace 来管理多个包的依赖关系。这样就可以一个测试项目一个包项目,包的相关功能就可以在测试项目中进行测试。

在最外层的项目中,如果我们想精准的控制某个子项目的命令,可以在父项目的 package.json 中添加

"scripts": {
  "p1": "pnpm --filter package1",
}

可以精准的去控制子项目。不用再切到子项目中去操作。这里的 package1 是子项目的名称。也就是子项目的 package.json 中的 name 属性。

pnpm 的一些指令

#安装软件包及其依赖的任何软件包 如果workspace有配置会优先从workspace安装
pnpm add <pkg>
#安装项目所有依赖
pnpm install
#更新软件包的最新版本
pnpm update
#移除项目依赖
pnpm uninstall
#运行脚本
pnpm run
#创建一个 package.json 文件
pnpm init
#查看所有依赖
pnpm list (pnpm ls)