为什么选择PNPM?
在JavaScript的世界里,npm和yarn可能是最为人所熟知的包管理器。然而,这并不意味着他们就是最优的选择。相反,PNPM是一个值得你关注的强大工具。它解决了npm和yarn的一些痛点,例如项目间的依赖项重复和大量占用硬盘空间的问题。因此,如果你是一个对性能有严格要求,或者是希望更高效地管理你的项目依赖的开发者,PNPM可能是你的理想选择。
PNPM的优势
空间效率高
PNPM的空间效率高:PNPM通过存储单一版本的包在全局目录中,然后在项目中创建到这些包的链接,从而避免了在每个项目中都存储重复的依赖包,节省了大量的硬盘空间。
硬链接是一个指向文件系统中文件数据的引用。每个文件至少有一个硬链接,即其原始文件名。这有点类似于C语言中的指针,他将磁盘里原始的内存映射到操作系统的文件系统中。
软链接,又称为符号链接,是一个特殊的文件,该文件包含了指向另一个文件或目录的路径。
在PNPM中,它使用的是硬链接。这意味着在全局存储区中的包和在项目node_modules目录中的包都指向同一份数据,因此不会占用额外的硬盘空间。然而,它也使用了符号链接(软链接)来创建.node_modules子目录,以保证包的隔离性,防止包之间的冲突。
性能优化好
PNPM在安装曾经安装过的包时,会非常快,因为他只需要创建这个包的链接即可。因此安装包的速度通常比npm和yarn更快。
严格的包依赖关系管理
PNPM还采用了一个名为“严格模式”的特性,该模式确保项目只能访问在其package.json文件中明确声明的包。这避免了隐式依赖的问题,使得项目的依赖关系更加清晰和可管理。
硬链接
PNPM的优化,离不开硬链接机制。硬链接是文件系统中的一种链接,它直接指向文件数据的存储位置,而不是像符号链接那样引用另一个链接。硬链接的特点就是它们指向的是同一份数据,修改任何一个链接,都会影响到其他的链接。硬链接对于同一个文件可以有多个,且可以跨目录,但不能跨文件系统。
在PNPM中,硬链接的概念被用来优化 node_modules 的安装过程。当 PNPM 安装一个包时,它首先会把包下载到一个全局存储(pnpm store)中。然后,它会在项目的 node_modules 目录中创建一个指向全局存储的硬链接。这样,同一个包在不同的项目中可以共享同一份数据,而不需要在每个项目中都安装一份。此外,PNPM 还会使用符号链接来处理依赖关系。例如,如果包 A 依赖于包 B,那么 PNPM 会在 A 的 node_modules 目录中创建一个指向 B 的符号链接。这样,A 可以直接通过这个链接访问到 B,而不需要在 A 的 node_modules 目录中也安装一份 B。
全局存储 PNPM Store
随着你使用 PNPM 安装更多的包,全局存储(store)的大小确实可能会不断增长。当你在所有项目中都卸载了某个包,他并不会删除全局存储中对应的包文件。PNPM的这样做是为了下次安装时,可以更加快速。如果你希望给 Store 瘦身,PNPM提供了一些命令来帮助你管理和清理全局存储。
pnpm store prune
:这个命令会清理全局存储中不再被任何项目使用的包。它首先会找出所有还在使用的包,然后删除其余的包。这个命令可以帮助你清理那些已经不再需要的包,从而减小全局存储的大小。
pnpm store status
:这个命令会检查全局存储的完整性。它会找出那些已经损坏或丢失的包,这些包可能会占用不必要的空间。你可以使用 pnpm store prune
命令来清理这些包。
pnpm store gc
:这个命令是 "garbage collector" 的缩写,它会清理那些不再被 package-lock.yaml 文件引用的包。这个命令可以帮助你清理那些已经不再需要的包。
Monorepo 与 PNPM Workspace
Monorepo 是一种代码管理策略,其中在一个单一的版本控制仓库中管理多个项目或包。这些项目可能是互相关联的,也可能是完全独立的。Monorepo 的优点包括代码共享、跨项目的原子提交、以及统一的构建和测试环境。
PNPM 为 Monorepo 提供了良好的支持。它提供了一种称为 "workspaces" 的功能,可以让你在一个单一的仓库中管理多个包或项目。在 PNPM 的 workspaces 中,每个包都有自己的 node_modules 目录,并且可以有自己的依赖。然而,所有的包都共享一个全局存储,这样可以避免重复安装相同的包。
PNPM 的 Monorepo 支持有以下几个主要特性:
-
依赖关系链接:在同一个仓库中的包可以直接链接到彼此,而不需要发布到 npm。这使得跨包的开发变得非常容易。
-
共享的依赖:所有的包都共享同一个全局存储,这样可以避免重复安装相同的包,节省磁盘空间。
-
原子提交:你可以在一个提交中更新多个包,这样可以确保仓库的一致性。
-
统一的构建和测试:你可以在整个仓库中运行构建和测试命令,而不需要在每个包中单独运行。
为了在 PNPM 中使用 workspaces,你需要在 pnpm-workspace.yaml 文件中指定所有的包或项目的路径。
会用到的命令行参数
--filter
:可以用来选择在哪些包上运行命令。例如,pnpm recursive run test --filter @myorg/my-package
会只在 @myorg/my-package
这个包上运行 npm test
命令。
-w/-workspace
:用于在工作区根目录执行命令,当你在任何工作区的子包目录下使用 -w 参数执行命令时,该命令将在工作区的根目录下执行,而不是在当前子包目录下执行。
包过滤
在PNPM中,你可以使用多种方式来过滤包,特别是在大型的Monorepo项目中。以下是一些主要的过滤语法:
包名:最简单的方式就是直接使用包名,例如pnpm update lodash。
特定范围:如果你的包都在特定的范围下,你可以使用范围名称来过滤它们,例如pnpm update @myorg/*。
依赖关系:你可以使用...和^...语法来选择包以及它的所有直接和间接依赖者或依赖项。例如,pnpm update lodash...会更新lodash包以及所有直接或间接依赖lodash的包;pnpm update lodash^...会更新lodash包以及所有依赖于lodash的包。
文件路径:你可以使用文件路径来过滤特定的包,例如pnpm update ./packages/my-package。
选择器:你还可以使用选择器来过滤包。例如,pnpm update --filter lodash...会更新lodash包以及所有直接或间接依赖lodash的包。
否定选择器:你可以使用否定选择器来排除特定的包。例如,pnpm update --filter !lodash会更新所有包,除了lodash。
组合选择器:你可以组合多个选择器来过滤包。例如,pnpm update --filter lodash... --filter !lodash会更新所有直接或间接依赖lodash的包,但不包括lodash本身。
标签:存储,依赖,lodash,PNPM,Monorepo,pnpm,链接 From: https://www.cnblogs.com/orzmiku/p/17675054.html