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/

相关推荐
桥豆麻袋93931 分钟前
vite 初始化react项目
前端·react.js·前端框架
CHQIUU3 分钟前
使用 CDN 在国内加载本地 PDF 文件并处理批注:PDF.js 5.x 实战指南
开发语言·javascript·pdf
2401_837088503 分钟前
CSS相对定位与绝对定位
前端·css
梦想平凡43 分钟前
开元类双端互动组件部署实战全流程教程(第1部分:环境与搭建)
运维·服务器·前端·游戏·node.js
HelloRevit1 小时前
React -> AI组件 -> 调用Ollama模型, qwen3:1.7B非常聪明
前端·react.js·前端框架
geovindu1 小时前
javascript: Multi-page PDF in Canvas using PDFJS 5.1
前端·javascript
暮 夏1 小时前
利用session在html和MySQL实现登录
前端·mysql·html
吃面必吃蒜1 小时前
前端实战中的单例模式:以医疗药敏管理为例
前端·javascript·单例模式·设计模式
哎哟喂_!1 小时前
Node.js vs 浏览器中的JavaScript:区别全解析
开发语言·javascript·node.js
OpenTiny社区1 小时前
Node.js 技术原理分析系列9——Node.js addon一文通
node.js