在之前的文章 果断放弃npm切换到pnpm–节约磁盘空间(256G硬盘救星) 中有提及 npm 扁平化带来的幽灵依赖 问题,但没有特别展开,这段时间实际业务中遇到了该问题,特整理如下:

️ 问题描述:项目使用 npm 安装依赖可以正常运行,而使用 pnpm 安装依赖运行报错!

node-emoji 为例:其是一款表情符号查找和解析工具,它依赖了 @sindresorhus/is 用于值类型检查。

{
  "name": "node-emoji",
  "version": "2.1.3",
  "dependencies": {
    "@sindresorhus/is": "^4.6.0",
    ...
  }
}

使用 npm/pnpm 新增 node-emoji 依赖

$ npm install node-emoji --save
$ pnpm add node-emoji --save

示例:我 ️ ??

const emoji = require('node-emoji') 

console.log(emoji.emojify('我 :heart:  :cn:')) 

均可正常执行,我们修改代码如下:

const emoji = require('node-emoji') 
+ const is = require('@sindresorhus/is')

console.log(emoji.emojify('我 :heart:  :cn:')) 
+ console.log(is('李刚')) // string

npm 可正常执行!pnpm 报错:Error: Cannot find module '@sindresorhus/is'

在这里插入图片描述左侧:npm;右侧:pnpm


通过安装的结构,便可以察觉问题:

  • 使用 npm 安装,所有依赖都被提升到了 node_modules 下(npm@3之后的依赖扁平化,解决路径地狱);
  • 使用 pnpm 安装,只有直接依赖(package.json dependences 中声明)安装在 node_modules 下,其他在 .pnpm(扁平化) 目录下。

不再 node_modules 下,所以项目中无法直接引用!

pnpm 好处:

  1. 通过软链的形式,使得 require 可以正常引用;同时对非真正依赖的项目做隔离(避免引用依赖的混乱)

    $ ls -li node_modules/node-emoji                                 
    30559101 lrwxr-xr-x  1 ligang  staff  46  8  6 16:59 node_modules/node-emoji -> .pnpm/node-emoji@2.1.3/node_modules/node-emoji
    
  2. .pnpm 的存在避免了循环引用和层级过深的问题(扁平化)

    node_modules
    └─ .pnpm
    |  ├─ node_modules
    |  |		└─ @sindresorhus+is@4.6.0 -> ../../@sindresorhus+is@4.6.0/node_modules/@sindresorhus/is
    |  ├─ @sindresorhus+is@4.6.0
    |  └─ node-emoji@2.1.3
    |     └─ node_modules  
    |        └─ @sindresorhus/is -> ../../../@sindresorhus+is@4.6.0/node_modules/@sindresorhus/is
    └─ node-emoji
    
  3. 硬链使得不同项目相同依赖只存在一个副本,减少磁盘空间

    $ ll -li node_modules/.pnpm/@sindresorhus+is@4.6.0/node_modules/@sindresorhus/      
    
    30564598 drwxr-xr-x  6 ligang  staff   192B  8  6 17:52 is
    
    inode值文件类型权限链接计数文件拥有者文件群组大小修改日期名称
    30564598drwxr-xr-x6ligangstaff192B8月6日 17:52is

pnpm基于符号链接的 node_modules 结构

硬连接
软连接
inode \n 30564598
file2
file1
inode \n 30559101
file1
file2

解决方案:不推荐

如果缺少依赖太多,可以使用提升选项。此选项官方不推荐。

pnpm install --shamefully-hoist

在这里插入图片描述

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部