的node_modules结构设计pnpm的node_modules结构设计分析在pnpm之前,先说说npm目前存在的一些问题。通常我们使用npminstall命令后,node_modules会显示如下类似的内容。之所以采用这种扁平的外观结构,当初的初衷是好的。为了更好的利用资源,把所有的依赖放在最顶层,这样每个依赖就不会嵌套太深,导致很多重复的依赖文件。但是有了这个文件结构,一步步使用之后,会暴露出两个问题。Ghost依赖版本冲突。幽灵依赖就是当你引用npm包的时候,你会发现一些package.json中没有出现的包也可以被引用。这是ghost依赖,因为在install下载npm包的时候,npm包也有它的依赖,也会被下载,但是下载的依赖也会存在node_modules同级下,会导致直接引用版本冲突因为不同的依赖可能依赖不同的包版本,但是在node_modules的同一层只能存在一个包的一个版本号。如果有不同的版本号,则只能存在于依赖包的node_modules中,会导致重复资源├──package-A@1.0|──package-B@1.0├──package-C@1.0│└──package-A@2.0│└──package-B@2.0├──package-D@1.0│└──package-A@2.0│└──package-B@2.0pnpm出现的时候前端npm苦了很久,出现了pnpm,其结构在pnpm官网的介绍中有简单说明:store+linkstore是dependencies的实际存放位置,Mac/linux在{homedir}>/.pnpm-store/v3,windows在当前盘/.pnpm-store/v3。这样会有一个好处,当你在多个项目中使用同一个依赖时,你不用重复下载,大大减少了存储空间。链接指的是符号链接(SymbolicLink)和硬链接(HardLink)。SymbolicLink是一个特殊的文件,它以绝对路径或相对路径的形式包含对其他文件或目录的引用。它的存在不依赖于目标文件。如果目标文件被删除或移动,指向目标文件的符号链接仍然存在,但它们将指向一个不再存在的文件。与SymbolicLink相比,HardLink不是指向一个文件,而是指向一个inode。索引节点是文件系统的一种数据结构,用于描述文件系统对象。所以即使你改变了目标文件的内容或位置,HardLink仍然指向目标文件,因为inode指向文件然后以react为例。pnpmaddreact后,在node_modules终端输入tree-a-L3,得到如下node_modules结构├──.modules.yaml├──.pnpm│├──js-tokens@4.0.0││└──node_modules│├──lock.yaml│├──loose-envify@1.4.0││└──node_modules│├──node_modules││├──.bin││├──js-tokens->../js-tokens@4.0.0/node_modules/js-tokens││└──loose-envify->../loose-envify@1.4.0/node_modules/loose-envify│└──react@18.2.0│└──node_modules└──react->.pnpm/react@18.2.0/node_modules/reactnode_modules除了.pnpm之外只有一个react。这个反应只是一个SymbolicLink。node.js在解析的时候会找到react的真正位置node_modules/.pnpm/react@18.2.0/node_modules/react.pnpm是把所有的依赖放在同一层的文件夹里,每个包都可以通过path.pnpm/
