pnpm v8版本升级变化关注点(前瞻速攻版)

pnpmv8引入了默认开启auto-install-peers,解决peerDependencies问题,但可能在某些场景下安装未预期的依赖。lockfile版本升级到v6,save-workspace-protocol策略改变,以及默认启用lowest-direct策略来缓解供应链攻击。尽管有新特性,但在monorepo管理中,推荐使用Monorepo丝滑方法论,而非依赖于新的解决peerDependencies困境的选项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

pnpm v8.0.0-alpha.0 版本已经发布,包含少量变化,但其中还是有令人在意的点的。

本文将默认读者拥有大部分 pnpm v7 版本的知识储备,进行 v8 版本的前瞻速攻。

安装方法

目前通过指定 Tag 方式可以安装 v8 alpha 版:

  npm i -g pnpm@next-8

所有 Tag 详见:npm > pnpm version

由于距 pnpm v8 正式发布还有一段距离( alpha > beta > latest ),本文可能存在部分内容过时,请仔细甄别。

从 v6 升级至 v7

本文是 v7 升级 v8 ,若你需从 v6 升级,可先参考 :

正文

下面对 changelog 逐条分析。

auto-install-peers is true by default

在 pnpm v7 版本之初,strict-peer-dependencies 是默认打开的,这会导致不安装 peerDependencies 就会安装报错(除非打开 auto-install-peers),引发了大量社区反馈,极大降低了 pnpm 的易用性,我们在 v6 升级 v7 的文章中也推荐设定 strict-peer-dependencies=false 避免不必要的报错问题。

所以 strict-peer-dependenciesv7.13.5 又调整回默认 false

v7 的计划失败了,到了 v8 ,可以看出 pnpm 希望通过默认打开 auto-install-peers=true 的方式解决 peerDependencies 的问题,但这会导致在本地 package.json 中的 peerDependencies 也被安装,一个例子如下:

// package.json
{
  "peerDependencies": {
    "react": "^18"
  }
}

此时我们不期望 react 被安装,因为我们没有在 dependencies / devDependencies 指明安装他,但由于 auto-install-peers 被默认打开,最终仍然会安装 react

进一步,在实际业务中,分情况考虑可能造成的影响:

  1. 普通场景:在本地开发时,按照开发规范,我们必然对 peerDependencies 的依赖也在 devDependencies 指定一份,但不在 dependencies 指定,所以该依赖是肯定会被安装的,auto-install-peers 不会对我们造成影响。

  2. monorepo 场景:在 monorepo 时我们有 Monorepo丝滑方法论 ,依赖总唯一,所以无需担心 auto-install-peers 问题。

通过分析我们得知 auto-install-peers=true 默认打开一般情况对我们没有实质性影响。

下面我们举两个会存在问题的 case 供参考:

  1. npm link 调试等情况,导致 peerDependencies 被意外安装,但 npm link 早已过时不再使用,这种情况是很少见的。

  2. 不遵守 npm 包开发规范,导致 peerDependencies 被意外安装,我们也不展开该极少数的情况。

由于 auto-install-peers 几乎不会对我们造成影响,加上使用包管理工具应该向 零配置 靠拢,本文不再推荐手动关闭 auto-install-peers 该选项,而是拥抱变化,若有极少数的特殊需求,你可能需要关闭该行为:

// .npmrc
auto-install-peers=false
The registry field is removed from the resolution object in pnpm-lock.yaml

lock 文件层面格式的优化,对我们使用没有直接影响,可以忽略。

save-workspace-protocol is rolling by default

save-workspace-protocol 决定了在 pnpm monorepo 中,手动安装工作区内同名包的版本添加行为:

  pnpm add foo

如我们的 workspace 含有 foo 该包,在 v7 我们安装该包得到的是:

  "foo": "workspace:^1.0.0"

现在 v8 默认 rolling 策略得到的将是:

  "foo": "workspace:^"

由于我们极少在工作区内手动运行安装同名包的命令,往往是手动添加 workspace 内的其他包,并且使用 * 格式:

// package.json

  // 手动添加要使用的 monorepo 内其他包
  "foo": "workspace:*"

所以此变化不会影响我们的使用,可以忽略。

When there’s a files field in the package.json, only deploy those files that are listed in it

该命令涉及到 pnpm deploy 相关,由于 prune 功能还不够成熟,考虑到没有得到 nextjs 示例项目的推荐,我们几乎不会使用,可以忽略。

Use lockfile v6 by default

v6 是 pnpm 的下一个大版本的 lockfile 格式,目前格式版本是 5.4

// pnpm-lock.yaml
lockfileVersion: 5.4

// ...
// pnpm-lock.yaml (pnpm v8)
lockfileVersion: '6.0'

// ...

6.0 lockfile 格式相比 5.4 有 80% 内容基本一致,变化主要集中在对依赖的 版本描述 上,以下给出一个大致的 demo :

// old 5.4

  /@ant-design/colors/6.0.0:
    resolution: { ... }
    dependencies:
      '@ctrl/tinycolor': 3.4.0
// new 6.0

  registry.npmjs.org/react@18.0.0:
    resolution: { ... }
    name: react
    version: 18.0.0
    engines: {node: '>=0.10.0'}
    dependencies:
      loose-envify: ...
    dev: true

可以看出 6.0 新版 lockfile 对依赖的描述从 单行 变成了 多行 ,但对我们实际使用没有影响,运行 pnpm i 刷新 lock 文件即可,该变化可以忽略。

注:pnpm 早在 v7.24.2 就预先放出了该 6.0 lockfile 版本的配置项,同时官方仓库也第一时间使用了 6.0 新版 lockfile 格式,没有 Breaking change ,可以放心使用。

resolve-peers-from-workspace-root is true by default

resolve-peers-from-workspace-root 该选项主要用来解决 monorepo peerDependencies 困境 问题,当多子包需要同一个 peerDependencies 时,无需手动配置提升,而是在 root 安装唯一的该依赖,即可保证全局唯一性。

但提升至 root 只适合要求的版本范围全部匹配,可以唯一提升的依赖,不支持精细版本控制,同时会污染 monorepo 根 root ,造成不必要的隐形全局依赖和心智负担,我们在 Monorepo管理方法论和依赖安全 中明确指出 严禁安装 monorepo 全局依赖 ,故此选项不推荐使用,同时我们有 Monorepo丝滑方法论 实现更好的 monorepo 多实例解法,轮不到 resolve-peers-from-workspace-root 发挥作用,可以忽略该变化。

需要注意的是, Monorepo丝滑方法论 往往和框架挂钩,对于小型 monorepo 项目,若支持不了 丝滑方法论 的实现,可以勉强接受 resolve-peers-from-workspace-root 这种解决 peerDependencies 困境的方法。

publishConfig.linkDirectory is true by default

随着 package.json#exports 的流行,更多的项目会采用非根发布 npm 包(如 jotai 等),publishConfig.linkDirectory 是对于此类项目的优化支持,不会直接影响到我们的使用,可以忽略。

resolution-mode is lowest-direct by default

近年 npm 供应链攻击的 case 偶然发生,目前比较好的 被动 管控手法有:

  1. 预打包依赖:参考 Nextjs / Umi 预打包策略,实现略。

  2. pnpm time-basedtime-based 策略可以基于包的最后发布时间来确保你使用的依赖在某个发布时间前,从而规避供应链发新包导致的攻击问题,但对于非自建 npm registry 需要花费更多时间读取 npm 包元信息,目前 pnpm 官方采用此策略,此处不做展开。

  3. pnpm lowest-directlowest-direct 是另一种 pnpm 推出的 缓解 供应链攻击的手段,他等价于锁定你的直接依赖版本(解析为 semver 的最低依赖版本),比如 ^1.0.0 也只会安装 1.0.0 最低版本,而不是最新的 ^1 版本,这等价于你锁定该依赖到 1.0.0 ,若你需要 1.2.0 版本也需要写为 ^1.2.01.2.0 ,该行为可以从一定程度上 缓解 供应链发新包导致的攻击,也不会承受 time-based 策略拉取 npm 元信息造成的依赖安装变慢。

默认 lowest-direct 策略后,我们可以直接性的 缓解 供应链攻击造成的影响,即使在没有 lock 文件时也可以每次都安装到确定的依赖版本。

但相应的成本是:必须显示的提升依赖版本号来做依赖升级,否则无法安装到最新版本,使用解析到的最低版本极有可能遭受未知的 bug ,从而浪费大量排查时间,请在使用 pnpm v8 时格外注意手动升级依赖至最新版本防止未知的 bug

Direct dependencies are deduped. So if the same dependency is both in a project and in the workspace root, then it is only linked to the workspace root

该变动是为了配合 resolve-peers-from-workspace-root 的行为,忽略即可。

Create a lockfile even if the project has no dependencies at all

对我们没有直接影响,忽略。

总结

通过分析 pnpm v8 alpha 的变化我们发现,只要遵守 pnpm v7 我们总结出来的 monorepo 方法论:

从 v7 升级至 v8 是几乎无损、水到渠成顺利的。

另外,请留意在 v8 状态下你的依赖是 锁定等价 的最低版本,请定期升级版本防止不必要的 bug ,并在出现 bug 时升级依赖排查。

若你需要进一步了解 monorepo ,提供如下内容参考:

以上。

Pnpm Beta 版追加

Date:2023-03-07

pnpm v8.0.0-beta.0 已经释出,新增了 dedupe-peer-dependents 选项,用于缓解 peerDependencies 重复问题,现在以下配置搭配将在 v8 中默认开启:

# 优先从 root 解析 peerDependencies ,尽可能的提升唯一性
resolve-peers-from-workspace-root=true
# 去除重复的 peerDependencies ,尽可能减少重复性
dedupe-peer-dependents=true

pnpm 通过这两个配置,可以尽力而为的缓解 peerDependencies 多实例、重复对项目造成的致命问题。

但他仍然无法像 alias 重定位一样彻底保证项目单实例,同时无法解子包调试热更新问题,所以此处更推荐优先使用 Monorepo 丝滑方法论 ,由于丝滑方法论需要在 webpack 或内置于框架中实现,在 pnpm >= 7.29.0 版本下,若你环境受限无法落地丝滑方法论但又遭遇 peerDependencies 问题时,可以打开这两个选项缓解 peerDependencies 问题。

### npm 和 pnpm本兼容性 pnpm 是一种高效的包管理工具,其设计旨在解决传统 npm 安装过程中产生的重复依赖问题。然而,pnpm 对 Node.js 的最低本有一定要求,这直接影响了它与 npm 的兼容性[^2]。 #### 节点环境的要求 pnpm 需要至少 Node.js v14.6 才能正常运行。这意味着如果用户的 Node.js 本低于此标准,则无法成功安装或使用最新本的 pnpm。对于具体的本映射关系,官方提供了一个详细的页面用于查看历史本的支持情况[^2]: - **访问链接**: [https://r.pnpm.io/comp](https://r.pnpm.io/comp) #### npm 和 pnpm本对应表 虽然两者并非严格绑定在一起,但在实际操作中,推荐保持 npm 和 pnpm 的主要本一致以获得最佳体验。以下是基于社区反馈整理的部分本对照信息: | npm Version | Recommended pnpm Version | |-------------|---------------------------| | 6.x | 5.x | | 7.x | 6.x | | 8.x | 7.x | 需要注意的是,随着技术的发展,上述表格可能会有所变动。因此建议定期查阅官方文档获取最新指导[^4]。 #### 实际应用中的注意事项 当遇到诸如 "缺少node-sass" 等错误时,除了更换镜像源或者尝试其他包管理器如 yarn 外,还可以手动下载预编译二进制文件放置于指定目录下解决问题[^1]。例如针对 Windows 平台上的特定本缺失状况采取如下措施: ```batch set SASS_BINARY_PATH="C://Users//AAAAAA//AppData//Roaming//npm-cache//node-sass//4.13.1//win32-x64-79_binding.node" npm install node-sass@3.4.1 ``` 这样做的好处在于能够绕过网络不稳定带来的困扰,同时确保本地构建流程顺利进行[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值