发布于 2026-01-06 0 阅读
0

pnpm 与 Lerna:多包仓库中的过滤

pnpm 与 Lerna:多包仓库中的过滤

几乎每个人都听说过Lerna,它是一款“用于管理包含多个包的 JavaScript 项目的工具”。但鲜为人知的是pnpm,它是一款快速且磁盘空间占用极低的 JavaScript 包管理器。Lerna 和 pnpm 都致力于改进多包仓库 (MPR) 的工具。对于 Lerna 而言,这正是其诞生的初衷。而对于 pnpm 来说,MPR 支持则是一个不错的附加功能,它通过一组名为recursive 的命令来实现。当然,Lerna 和 pnpm 在管理多包仓库的方式上存在诸多差异。在本文中,我想比较一个看似简单的方面:过滤。

在 MPR 中进行过滤非常重要,因为在开发过程中,更改主要集中在一两个软件包中。如果只有少数软件包被修改,那么对整个代码库运行命令就没有意义了。

Lerna 中的过滤

Lerna 中的过滤功能(截至目前v3.2.1)是通过以下标志实现的:

  • scope- 只包含名称与给定 glob 匹配的包。
  • include-filtered-dependents--scope- 无论是否为、--ignore或,运行命令时都包含所有传递依赖项--since
  • include-filtered-dependencies--scope- 无论是否启用、--ignore或,运行命令时都应包含所有传递依赖项--since
  • ignore- 排除名称与给定 glob 匹配的包。
  • private- 包含私有软件包。传递 `--no-private` 参数可排除私有软件包。
  • since- 仅包含自指定 [ref] 以来更新过的软件包。如果未传递 ref,则默认为最新标签。

这些标志使得 Lerna 的过滤功能非常强大。然而,它们输入起来相当麻烦。假设你下载了一个代码仓库,并且只想处理其中的login-page一个组件。你需要运行 `installation` 命令来安装该组件login-page及其所有依赖项:

lerna bootstrap --scope login-page --include-filtered-dependencies
Enter fullscreen mode Exit fullscreen mode

或者,您可能更改了某个名为 `<component_name>` 的组件site-header,并希望对所有依赖包运行测试:

lerna run test --scope site-header --include-filtered-dependents
Enter fullscreen mode Exit fullscreen mode

这些旗帜不仅难以输入,而且难以记忆,还容易混淆。

pnpm 中的过滤

与 Lerna 不同,pnpm 使用特殊的包选择器语法来限制其命令。因此,您无需记住一组冗长的标志名称,只需记住一个非常容易记忆的选择器语法即可。

截至版本 3.0 2.15.0,pnpm 支持以下选择器:

  • <pattern>- 将范围限制为与给定模式匹配的包名称。例如foo@bar/*
  • <pattern>...- 包括匹配软件包的所有直接和间接依赖项。例如:foo...
  • ...<pattern>- 包括所有匹配软件包的直接和间接依赖项。例如...foo...@bar/*
  • ./<directory>- 包含给定子目录中的所有软件包。例如:./components
  • .- 包括当前工作目录下的所有软件包。

这些过滤器可以通过标志指定,也可以在命令末尾的--filtera 之后指定。--

注意:截至目前v2.15.0,后面的过滤--不受支持run,,exectest

所以,如果你想引导程序login-page及其所有依赖项,可以使用 pnpm 按照以下方式操作:

pnpm recursive install -- login-page...
Enter fullscreen mode Exit fullscreen mode

如果要对某个组件site-header及其所有依赖项进行测试,请使用...<pattern>以下选择器:

pnpm recursive test --filter ...site-header
Enter fullscreen mode Exit fullscreen mode

当然,您可以根据需要组合任意多个选择器:

pnpm recursive update -- ...site-header login-page... ./utils @style/*
Enter fullscreen mode Exit fullscreen mode

上述命令更新了以下依赖项:

  • site-header
  • 家属site-header
  • login-page
  • 依赖项login-page
  • 位于该utils目录中的所有软件包
  • @style范围内的所有包

pnpm 可能还没有 Lerna 提供的所有功能,但对许多用户来说可能已经足够了。

如果你还没有听说过 pnpm,我建议你阅读《扁平化的 node_modules 并非唯一途径》,这篇文章解释了 pnpm 创建的独特 node_modules 结构。

速查表

Lerna v3.2 pnpm v2.15
--scope my-component -- 我的组件
--scope toolbar-* -- 工具栏-*
--scope my-component --include-filtered-dependencies -- 我的组件...
--scope my-component --include-filtered-dependents -- ...我的组件

最初发布于pnpm 博客

文章来源:https://dev.to/zkochan/pnpm-vs-lerna-filtering-in-a-multi-package-repository-587i