Node十六章(pnpm原理及软硬链接)

1.硬链接和软链接

  • 硬链接(hard Link)
    • 硬链接是一个电脑系统中多个文件平等共享的使用 一个存储单元
    • 删除一个文件,其他文件可以继续使用
  • 软链接(soft Link 或者符号链接symbol Link)
    • 其包含有一条以绝对路径或者相对路径 的形式指向其它文件 或者目录引用(其实就是快捷方式)
    • 当删除了源文件 软连接 的文件就无法使用

注意:硬链接可不是复制文件,可以参考下面这张图

2.使用硬链接和软链接与拷贝的区别

  • 文件的拷贝:文件的拷贝每个人都非常熟悉,会在硬盘中复制出来一份新的文件数据;

    • window copy foo.js foo_copy.js
    • Macos cp foo.js foo_copy.js
  • 文件的硬链接:

    • window : mklink /H aaa_hard.js aaa.js
    • Macosln foo.js foo_hard.js
  • 文件的软连接

    • window : mklink aaa_soft.js aaa.jss
    • Macos ln -s foo.js foo_copy.js

3.pnpm到底做了什么呢?

  • 当使用npmyarn 时,如果你有100 个依赖,并且所有依赖都有一个相同的依赖包,那么,你在硬盘上就需要保存100 份该相同依赖包的副本

  • 如果是使用pnpm,依赖包将被存放在一个统一的位置

  • 如果你对同一依赖包使用相同的版本 ,那么磁盘上只有这个依赖包的一份文件

  • 如果你对同一依赖包需要使用不同的版本 ,则仅有版本之间不同的文件会被存储起来

  • 所有文件都保存在硬盘上的统一的位置:

  • 当安装软件包时,其包含的所有文件都会硬链接到此位置,而不会占用额外的硬盘空间

  • 这让你可以在项目之间方便地共享相同版本的依赖包

  • 解释下面图片

    • npm/yarn的痛点:每个项目独立存储依赖文件,导致重复占用磁盘空间(如中间图彩色矩形重复堆叠);
    • pnpm的突破:用全局硬链接保存单一依赖副本 ,项目通过符号链接引用(图最右侧中心节点向外发散连接),避免重复存储。

4.pnpm/npm/yarn对比的直观差异

工具 依赖存储方式 安装速度 磁盘占用 依赖隔离性
npm 本地缓存复制+扁平化结构 中(可能幻影依赖)
yarn 扁平化结构 yarn.1.x采用的是本地缓存复制 yarn.2.x采用的全局缓存复用 较快 中(可能幻影依赖)
pnpm 全局硬链接+项目符号链接 最快 最低 强(严格隔离)
  • 本地缓存复制: 每个依赖都存储一份,浪费空间
  • 全局缓存复用 :缓存单独放在一个地方,要用直接拿来用,节省空间 pnpm 也差不多,用链接指向全局仓库

5.幻影依赖是什么?

  • 如图:我的依赖项目devDependencies 只有一个依赖 vite, 因为npm5.xk开始安装的依赖都是扁平化的
    • vite这个插件又依赖其他插件,所以看到除了vite这个打包工具还有很多其它插件在外面
  • 现在index.js去使用**非自己安装的依赖nanoid**这个插件,我并没有下载nanoid这个插件 但是还是使用成功
    • 这就是幻影依赖 ,我并没有下载这个依赖,只是因为vite这个打包工具在依赖他,因为扁平化原因我也能使用
    • 这是一个不规范的问题 ,如果我在项目中使用了幻影依赖 ,并没有去下载,如果我们后面更新vite, vite后面不依赖这个插件,node_modules就会删除这个插件,此时我们项目就会报错
js 复制代码
import { nanoid } from 'nanoid';
console.log('nanoid', nanoid()); // nanoid etubJqBXElEm5uw_xaQKk

5.1pnpm是怎么解决的?

  • pnpm采用则是非扁平化node_modules目录

    • 当我们使用pnpm安装自己的依赖在node_modules 第一层都是软链接,这样避免了幻影依赖
    • 不是我们安装的依赖是不会出现在第一层的硬链接的依赖 都是放在.pnpm这个文件中
    • 插件依赖另一个插件,另一个插件的依赖项软链接 会放在这个插件的node_modules
    • 如图所示:软链接最右边都有一个小箭头
  • 第一张图 所示:打开node_modules 首先我们看到 vite 快捷方式(软连接) 和.pnpm.bin三个文件目录

    • vite软链接指向.pnpm文件夹下存在真实的[email protected]就是硬链接指向 .pnpm store
    • vitenode_modules中又依赖其他几个包,其他几个依赖包也是软链接 指向.pnpm文件目录的硬链接的依赖包
  • 第二章官方图 所示: node_modules下我们就安装了bar插件

    • bar软链接指向.pnpm 文件目录中的 [email protected]这个硬链接,这个硬链接指向 .pnpm store

    • 但是[email protected]插件又依赖foo这个插件,这个foo也是一个软链接

    • foo软链接 又指向 .pnpm文件目录中的 foo@1.0.0 硬链接,这个硬链接指向 .pnpm store

    • .pnpm store也是一个硬链接 此时他指向的就是磁盘中的真实数据

5.2 pnpm的基本使用

npm 命令 pnpm 等价命令
npm install pnpm install
npm install pnpm add
npm uninstall pnpm remove
npm run pnpm

5.3 pnpm store 存储位置

  • pnpm 7 及更早版本中,存储可能始终位于用户主目录下,如 C:\Users\username\AppData\Local\pnpm\store
  • pnpm 7之后 .pnpm store位置发生了变化
    • 假如我的项目在 F盘 下 我安装依赖pnpm install 此时 F盘根目录会创建 .pnpm-store ,所有F盘pnpm install 安装的依赖最终都会指向这里
  • 为什么要更换位置?
    • 统一位置可能导致跨磁盘复制依赖,增加磁盘空间占用和降低安装速度。
    • 除了效率,还有文件系统限制、用户体验改进和多磁盘环境的适配需求
版本 默认存储位置 多磁盘支持 性能优化
pnpm 7 及更早 用户主目录(如 C:\Users\username\AppData\Local\pnpm\store 需要手动配置,自动创建可能不明确 可能跨磁盘复制,效率较低
pnpm 8 及之后 每个磁盘根目录(如 F: .pnpm-store 自动创建,明确支持多磁盘存储 确保同一磁盘硬链接,效率更高
  • 可以通过命令查看位置 :获取当前活跃的store目录

    • pnpm store path
  • 清理当前活跃store 目录里面当前未被引用的包来释放store的空间

    • pnpm store prune

更多命令和用法可以参考pnpm的官网:pnpm.io/zh/

相关推荐
清弦居士几秒前
解锁 Ant Design MCP 组件查询新姿势:大模型组件查询新范式
前端·mcp
天天扭码5 分钟前
LeetCode 题解 | 1.两数之和(最优解)
前端·javascript·算法
冉冉同学8 分钟前
【HarmonyOS NEXT】解决微信浏览器无法唤起APP的问题
android·前端·harmonyos
广龙宇11 分钟前
【Web API系列】Web Shared Storage API之WorkletSharedStorage深度解析与实践指南
前端
逍遥德17 分钟前
前端工程化-包管理NPM-package.json 和 package-lock.json 详解
前端·npm·json
一只小风华~18 分钟前
Web前端 (CSS篇)
前端·css·html·html5
HelloRevit22 分钟前
npm install 版本过高引发错误,请添加 --legacy-peer-deps
前端·npm·node.js
工九度24 分钟前
2025前端社招最新面试题汇总- 场景题篇
前端·javascript
AronTing24 分钟前
状态模式:有限状态机在电商订单系统中的设计与实现
前端·设计模式·面试
这可不简单25 分钟前
git push 受阻,原是未拉取代码惹的祸
前端·git·面试