包管理器是工程化的重要环节【核心模块复用】 是用于自动化处理软件包(库、框架等)的安装、更新、配置和删除的工具。在 JavaScript 和 Node.js 生态系统中,最常用的包管理器包括 npm、Yarn 和 pnpm。它们简化了依赖管理和项目构建过程,使得开发者可以更专注于编写业务逻辑。
npm产生
随着 Node.js 的推出,开发者需要一种管理众多 JavaScript 库和模块的方法,npm(Node Package Manager)由此诞生。
npm 于2010年被引入,很快成为 Node.js 生态系统中分享和管理模块的标准方式。其中 node_modules
目录就是npm用来局部安装依赖的地方,使得不同的项目可以使用不同版本的包,而不会互相干扰。随着时间的推移,npm 还成为了一个庞大的开源库生态系统,目前已是世界上最大的软件注册机构。
然而,随着 npm 的快速成长,一些问题也随之而来,比如 node_modules 随着依赖的嵌套,体积越来越大。
在 npm2 及以前,每个包会将其依赖安装在自己的 node_modules
目录下,这意味着每个依赖也会带上自己的依赖,形成一个嵌套的结构,结构如下:
这样的结构虽然解决了版本冲突、依赖隔离等问题,但却有几个致命的缺点:
- 磁盘空间占用:每个依赖都会安装自己的依赖,导致了大量的重复,特别是在多个包共享同一依赖的场景下。
- 深层嵌套问题:这种嵌套结构在文件系统中造成了非常长的路径。
- 安装和更新缓慢:每次安装或更新依赖时,npm 需要处理和解析整个依赖树,过程非常缓慢。
pnpm的出现
简介:pnpm 是一种新型的包管理器,它解决了传统 npm 和 Yarn 在磁盘空间利用率上的不足,采用了一种称为“内容可寻址存储”的方法来存储依赖包。pnpm.nodejs.cn/motivation
当使用 npm 时,如果你有 100 个项目,并且所有项目都有一个相同的依赖包,那么, 你在硬盘上就需要保存 100 份该相同依赖包的副本。然而,如果是使用 pnpm,依赖包将被 存放在一个统一的位置,因此:
- 如果你对同一依赖包需要使用不同的版本,则仅有 版本之间不同的文件会被存储起来。例如,如果某个依赖包包含 100 个文件,其发布了一个新 版本,并且新版本中只有一个文件有修改,则
pnpm update
只需要添加一个 新文件到存储中,而不会因为一个文件的修改而保存依赖包的 所有文件。 - 所有文件都保存在硬盘上的统一的位置。当安装软件包时, 其包含的所有文件都会硬链接自此位置,而不会占用 额外的硬盘空间。这让你可以在项目之间方便地共享相同版本的 依赖包。
最终结果就是以项目和依赖包的比例来看,你节省了大量的硬盘空间, 并且安装速度也大大提高了!
硬链接和软链接(符号链接)的概念:
-
硬链接(Hard Link)
- 概念:硬链接是文件系统中的一个链接,它指向磁盘上的数据。当创建一个硬链接时,实际上是在创建一个和原始文件相同的入口点,但是不占用额外的磁盘空间。这个新的链接和原始文件共享相同的数据块,任何一个文件的修改都会反映在另一个上。
- 特点:硬链接不能跨文件系统创建,也不能用于链接目录,但如果原始文件被删除,硬链接依然可以访问数据。
- 使用场景:当你想要在不同位置访问同一个文件内容,而又不想占用额外磁盘空间时,可以使用硬链接。比如,在多个项目中共享相同的库文件,但不需要复制这个文件多份。
-
软链接(符号链接,Symbolic Link)
- 概念:软链接是一个特殊类型的文件,它包含了另一个文件的路径。类似于 Windows 系统中的快捷方式。与硬链接不同,软链接可以指向目录,也可以跨文件系统。
- 特点:软链接指向文件或目录的路径,如果原始文件被删除,软链接就会失效,因为它的指向已经不存在了。
- 使用场景:软链接适用于需要引用特定位置的文件或目录时,特别是当这些文件或目录可能会移动或变化时。它允许链接到另一个文件系统中的文件或目录。
pnpm硬链接 【类比maven依赖管理】
pnpm 通过使用全局的 .pnpm-store
来存储下载的包,使用硬链接来重用存储在全局存储中的包文件,这样不同项目中相同的包无需重复下载,节约磁盘空间。通过pnpm store path 获取位置
软链接(符号链接)【类比windows快捷方式】 代码演示
pnpm 将各类包的不同版本平铺在 node_modules/.pnpm 下,对于那些需要构建的包,它使用符号链接连接到存储在项目中的实际位置。这种方式使得包的安装非常快速,并且节约磁盘空间。
项目中依赖了 A,这时候可以通过创建软链接,在 node_modules 根目录下创建 A 软链指向了 node_modules/.pnpm/A/node_modules/A。此时如果 A 依赖 B,pnpm 同样会把 B 放置在 .pnpm 中,A 同样可以通过 软链接依赖到 B,避免了嵌套过深的情况。
硬链接 ln source_file hard_link 软连接 ln -s source_file hard_link