bun 和 pnpm 谁硬? 谁软?

Bun v1.3.14 引入了全局虚拟存储(global virtual store),

通过硬链接复用缓存、软链接构建隔离的依赖树,

在依赖管理和磁盘效率上正向 pnpm 看齐,两者越来越像了。

1. 软/硬链接的 JS 直觉

可以用 JS 对象引用,快速理解软硬链接。

硬链接:多个引用指向同一个对象。

删除其中一个引用,原对象不会销毁。

所有引用删除后,对象才会被回收。

bash 复制代码
const obj = { data: "Hello" };
const hard = obj;
delete obj;
console.log(hard.data); // "Hello"

软链接:只存储目标路径,动态查找资源。

一旦原文件/对象删除,软链接就会失效悬空。

bash 复制代码
const reg = { target: { data: "Hello" } };
const soft = () => reg.target;
delete reg.target;
console.log(soft()?.data); // undefined

总结:硬链接共享实体;软链接仅存路径。

2. Bun 和 pnpm:并非一硬一软

Bun 和 pnpm 底层同时支持硬链接、软链接。

二者无本质技术差异,只是默认策略不同。

pnpm:硬链接存真实文件,软链接构建依赖树。

天然依赖隔离,默认杜绝幽灵依赖。

Bun v1.3.14+(单项目):默认扁平 Hoisted 结构。

不使用软链接树,行为接近 npm / yarn。

新版支持全局虚拟存储,大幅节省磁盘。

核心区别:pnpm 默认软链接树,Bun 默认不用。

3. 什么是软链接树(核心概念)

软链接树是隔离式的 node_modules 目录结构。

真实包文件统一存放在虚拟存储目录。

项目目录依靠多层软链接,映射真实文件。

它可以严格隔离依赖层级,杜绝幽灵依赖。

Hoisted 扁平模式无软链接树,依赖全部平铺。

扁平模式兼容性好,但存在隐式依赖风险。

4. Bun 软硬链接代码示例

bash 复制代码
import { link, symlink, unlink, readFile, writeFile } from 'node:fs/promises';

await writeFile('orig.txt', 'Bun');
await link('orig.txt', 'hard.txt');   // 硬链接
await symlink('orig.txt', 'soft.txt'); // 软链接
await unlink('orig.txt');

console.log(await readFile('hard.txt', 'utf8'));
// soft.txt 读取报错 ENOENT

运行命令:bun run demo.ts

5. 幽灵引用

幽灵引用分为依赖、文件系统两层场景。

依赖层面:代码使用未声明的包。

因依赖提升本地可运行,线上极易报错。

文件系统层面:源文件删除,软链接残留。

访问悬空软链接,会抛出 ENOENT 错误。

6. 幽灵引用与 Bun 的关系

幽灵引用不是 Bun 造成的。

根源是项目编码、依赖管理不规范。

比如漏写依赖、依赖隐式提升、写死绝对路径。

Bun 只是更快暴露了这些不规范问题。

规范声明依赖,任意包管理器都无幽灵依赖。

7. bun i 链接器参数(--linker hoisted / --linker isolated)对比 + v1.3.14 新特性

Bun v1.3.14 新增全局虚拟存储。

多项目共享缓存,磁盘效率对齐 pnpm。

通过 --linker 可切换两种依赖布局策略。

| 参数 | -linker hoisted | -linker isolated | | :-- | :-- | :-- | | 依赖结构 | 扁平 node_modules | 严格隔离 node_modules | | 软链接树 | ❌ 不使用 | ✅ 启用隔离软链接树 | | 幽灵依赖 | ✅ 允许 | ❌ 严格禁止 | | 磁盘占用 | 极低(全局共享) | 极低(全局共享) | | 安装速度 | 极快 | 极快(差距<5%) | | 兼容性 | 兼容所有老旧项目 | 部分老包需要适配 |

hoisted(单项目默认)适用场景

  • • npm / yarn 老项目迁移

  • • 存在隐式依赖,暂时无法重构

  • • 需要传统扁平 node_modules 结构

isolated(Monorepo 默认)适用场景

  • • 全新项目,从零杜绝幽灵依赖

  • • Monorepo 多子包严格隔离

  • • CI 环境保障依赖声明完整

  • • 想用 Bun 性能 + pnpm 隔离能力

小结:兼容旧项目用 hoisted;严谨规范用 isolated。

8. Bun(v1.3.14+) 与 pnpm 完整对比

| 对比维度 | pnpm | Bun(v1.3.14+) | | :-- | :-- | :-- | | 底层能力 | 硬链接 + 软链接 | 硬链接 + 软链接(macOS 克隆优化) | | 缓存机制 | 全局 Store 共享 | 全局虚拟存储,对齐 pnpm | | 单项目结构 | 隔离软链接树 | 扁平 Hoisted | | Monorepo 结构 | 严格隔离 | 严格隔离(isolated) | | 防幽灵依赖 | ✅ 默认支持 | isolated 支持,hoisted 不支持 | | 磁盘效率 | 极高 | 极高(新版持平 pnpm) | | 安装速度 | 较快(10-15s) | 极快(3-5s,快 2-4 倍) | | 速度差异 | 无 | 两种模式差距<5% | | Monorepo 成熟度 | 行业标杆 | 快速迭代,基础完善 | | 生态兼容 | 稳定 100% 兼容 | 近 100%,原生模块需测试 | | 核心优势 | 稳定、隔离、省空间 | 极速、工具链一体化、新版省空间 |

选型建议

追求稳定、严格隔离、磁盘极致节省 → 选 pnpm。

追求极速开发、新版存储优化 → 选 Bun。

相关推荐
程序员buddha8 小时前
Spring Boot框架,类注入成 Bean的方式
java·spring boot·后端
用户8356290780518 小时前
使用 Python 创建 Excel 雷达图
后端·python
程序员cxuan8 小时前
还在用 xigh 拉满跑?大错特错
人工智能·后端·程序员
AI大模型8 小时前
被AI抢饭碗的Java程序员,后来都怎样了?
java·后端·ai编程
sTone873758 小时前
Electron 进程架构模型
前端·electron
ZC跨境爬虫8 小时前
跟着 MDN 学CSS day_25:(高级区块效果)
前端·css·html·tensorflow·媒体
Bug-制造者8 小时前
前端流式输出完全指南:原理、实现与工程化实践
前端
暴躁小师兄数据学院8 小时前
【AI大模型应用开发工程师特训笔记】第04讲(第7章):函数与模块
前端·人工智能·python
跟着珅聪学java8 小时前
ECharts subtext(副标题)边距开发教程
前端·javascript·echarts