npm 软链接和硬链接
硬链接(Hard Link)是文件系统中一种特殊的机制,它允许同一个文件在文件系统中拥有多个文件名(或路径)。你可以把它理解为文件数据的“别名”或“多个入口”。
核心概念
指向数据,而非文件名:
- 在大多数现代文件系统(如 NTFS, ext4)中,文件数据存储在磁盘的某个物理位置。
- 文件名(或路径)只是一个指向这些实际数据的“指针”或“入口”。
- 一个硬链接就是创建一个新的文件名(路径),但它指向的是同一个文件数据块,而不是复制数据。
共享数据:
- 通过硬链接创建的多个文件名,它们共享完全相同的数据。
- 无论你通过哪个名字去读取或修改文件内容,看到的都是同一份数据。修改其中一个,其他所有硬链接也会立即反映出这些修改。
没有“原文件”和“链接文件”之分:
- 与“快捷方式”或“符号链接”不同,硬链接之间是完全平等的。
- 你无法区分哪个是“原始”文件,哪个是“链接”。它们都是文件数据的有效入口。
删除行为:
- 删除一个硬链接(即删除一个文件名),并不会删除文件数据本身。
- 文件数据会一直保留,直到所有指向它的硬链接都被删除。
- 文件系统通过一个“链接计数”(link count)来跟踪有多少个硬链接指向该数据。只有当链接计数降为 0 时,文件数据才会被真正释放(删除)。
与符号链接(Symbolic Link / Soft Link)的区别
这是最容易混淆的概念,理解它们的区别很重要:
| 特性 | 硬链接 (Hard Link) | 符号链接 (Symbolic Link / Soft Link) |
|---|---|---|
| 本质 | 指向文件的数据块 | 指向文件的路径名(一个包含路径的文本文件) |
| 跨文件系统 | 通常不能跨不同的文件系统或磁盘分区 | 可以跨文件系统或磁盘分区 |
| 目标删除 | 删除目标文件后,硬链接仍然可以访问数据(数据未删) | 删除目标文件后,符号链接变成“悬空链接”(失效) |
| 目录支持 | 通常不允许为目录创建硬链接(防止循环) | 可以为目录创建符号链接 |
| 文件类型 | 只能链接到文件 | 可以链接到文件或目录 |
| inode | 所有硬链接共享同一个 inode(文件系统标识) | 符号链接有自己独立的 inode,指向目标的 inode |
举个例子
想象一个文件 original.txt,内容是 “Hello World”。
- 创建硬链接:你创建了一个硬链接
link.txt指向original.txt。- 现在,
original.txt和link.txt都指向硬盘上存储 “Hello World” 的那块数据。 - 用
cat original.txt和cat link.txt都会输出 “Hello World”。 - 如果你用
echo "New content" > link.txt修改了link.txt,那么original.txt的内容也会变成 “New content”。 - 如果你删除
original.txt,link.txt依然存在且可以正常读写,数据不会丢失。
- 现在,
- 创建符号链接:你创建了一个符号链接
symlink.txt指向original.txt。symlink.txt本身是一个小文件,里面只存着字符串 “original.txt”。- 当你访问
symlink.txt时,系统会先读取这个小文件,得知它指向original.txt,然后再去打开original.txt。 - 如果你删除了
original.txt,那么symlink.txt就变成了一个无效的链接,访问它会出错(”No such file or directory”)。
在 pnpm 中的应用
pnpm 利用硬链接的特性来实现高效的依赖管理:
- 全局存储:
pnpm将下载的包(如lodash@1.0.0)解压后,存储在全局的、内容可寻址的存储区(如~/.pnpm-store)的一个固定位置。 - 创建硬链接:当你的项目需要
lodash@1.0.0时,pnpm不会复制整个lodash文件夹到你的node_modules,而是在你的node_modules目录下创建一个指向全局存储中lodash@1.0.0数据的硬链接。 - 节省空间:即使有 100 个项目都使用
lodash@1.0.0,磁盘上也只有一份lodash的数据,node_modules里的lodash文件夹都是指向这份数据的硬链接,从而极大地节省了磁盘空间。 - 速度:创建硬链接是一个非常快速的文件系统操作(只是创建一个新目录项),远快于复制整个文件夹。
总结:硬链接是一种让多个文件名共享同一份数据的技术。pnpm 通过它实现了依赖的“一次存储,多处链接”,这是其高效节省空间和快速安装的核心原因之一。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 YianNotes!

