pnpm 发布 pnpm 12 版本,将原有的 TypeScript 和 Node.js 实现重写为原生 Rust 版本,同时刻意保留了 pnpm 11 的命令、参数、设置、锁定文件格式以及 node_modules 目录结构。此次发布旨在优化启动速度并降低文件系统开销,同时也不需要团队重新学习该包管理器或进行大规模迁移。
当缓存或 node_modules 目录已经存在时,性能提升最为显著。在 pnpm 定期更新的基准测试中,文件量较大的测试集,其全新安装时间从旧实现的 8.2 秒缩短至 Rust 实现的 5 秒。而在缓存、锁定文件和 node_modules 目录已经预热的状态下重复安装时,耗时从 472 毫秒降到了 15 毫秒。
单独进行的生产测试提供了进一步的证据。据 Socket 报道,由 Vercel 的 21 个项目组成的 Turborepo 工作区(包含 1670 个包),在六种场景下的安装时间中位数缩短了 64.4% 至 90.5% 不等。不过,由于原生 Corepack 工件体积更大,其首次未缓存启动速度慢了 11.1%,但缓存后的启动速度提高了 74.7%。
开发者可以通过以下方式安装该版本:
pnpm self-update next-12npm 标签 latest 仍然指向 pnpm 11,而 Homebrew、winget、Scoop 和 Chocolatey 在发布时均未提供 12 版本。安装指南还提供了 npm 和 standalone-script 选项,其中包括不需要 Node.js 的安装方式。
迁移影响预计比较有限,但各团队仍然应该查阅 pnpm 的兼容性指南。最有可能导致持续集成(CI)失败的变更,是移除了 pnpm install --resolution-only 命令,该命令现在已经被 pnpm peers check 所取代。托管在 GitHub、GitLab 或 Bitbucket 上的 Git 依赖项将通过规范的 HTTPS URL 进行解析,而私有 SSH 访问应通过 Git URL 重写进行配置。现在,Linux 系统会优先尝试硬链接(hardlinks),然后才是引用链接(reflinks),并且会报告 pnpm-workspace.yaml 中未知的键,而不会静默忽略。
该版本还引入了具有项目感知能力的全局二进制文件。全局安装的 Node.js、Deno 或 Bun 可以遵循当前项目指定的运行时。pnpm 现在可以配置 npm、Yarn 以及 Bun 本身,包括由 Git 托管的依赖项所请求的包管理器。确定性循环处理还能生成字节级一致的锁定文件,根据发布说明,在循环密集型工作区中,这能使对等节点的解析速度提高两到三倍,同时内存占用减少约 25%。
社区的讨论主要集中在原生工具的性能及其权衡上。前端工程师 Dennis Morello 将此次发布描述为“披着大版本号外衣的性能更新”,并且强调,他看到的工作流程依然是以前熟悉的那个。在关于 Socket 报道的一场讨论中,前 npm CLI 维护者 Darcy Clarke 认为,将包管理器保留在 JavaScript 技术栈中,能让共享的内部逻辑更便于迭代优化;而 pnpm 维护者 Zoltan Kochan 则回应道:用 Rust 重写 pnpm 比迁移到 ESM 更快。
在 Hacker News 上,一位评论者表示,对他来说,npm 是最好的工具:
我得出的结论是,虽然平淡无奇,但已经足够好了。对我来说,npm 就是最好的工具。它虽然不算特别快,但安装速度也还不错。考虑到我需要从头开始运行的次数比较多,这种速度上的差异并不重要。它很稳定,而且是 Node 的默认包管理器,所以我无需费心在持续集成(CI)管道中安装其他工具,等等……
对此,有人指出使用 npm 存在安全隐患,而 pnpm 是一个更好的替代方案:
说 npm “平淡乏味”实在是言过其实了。考虑到它的安全模型,我觉得用“充满刺激与挑战”这个词要贴切得多。
我已经切换到 pnpm 了。
npm 默认会运行你的依赖项的包生命周期管理脚本。你必须明确选择禁用这一功能。
在 npm、pnpm、yarn 和 bun 之中,它大概是最糟糕的包管理器了。
与 npm、Yarn 和 Bun 相比,pnpm 继续凭借其内容可寻址存储、严格的依赖项布局以及如今推出的原生二进制文件来凸显自身的优势。在 Bun 自有的基准测试套件中,Bun 的发布速度依然更快,但由于基准测试框架本身存在问题,导致宽泛的性能排名结果并不可靠,所以 pnpm 已经将 Bun 和 Yarn 从其公开发布的性能对比榜单中移除。
pnpm 是由 Zoltan Kochan 创建的开源 JavaScript 包管理器。它通过内容可寻址存储和硬链接在不同的项目之间实现包共享,既减少了文件重复,又比传统的扁平化 node_modules 布局更严格地执行了依赖声明。





