没事翻了翻项目中的node_modules文件夹看看有没有名字比较有趣的包, 忽然想起来, 以前只是知道这些是项目依赖包的依赖包, 那么如果被依赖的包又依赖了一个包, 甚至是循环依赖, 那么npm该如何处理呢? 又或者, 两个包依赖了不同版本的一个包, npm又是如何处理的呢? 带着这个疑问, 研究了下npm install的策略

当执行install命令后, npm将以以下顺序执行install的动作

  1. 加载现有的node_module树
  2. 克隆树
  3. 获取package.json和各种元数据, 并添加到克隆树中
  4. 添加缺少的依赖关系, 同时, 依赖会被尽可能的添加到树的顶部, 且不会破坏其他任何模块
  5. 将原始的树和克隆的树进行比较, 并列出将原始树转换为克隆树的动作
  6. 执行所有动作, 最深的优先, 动作包括安装, 更新, 删除和移动

对于循环依赖的问题, 当包文件夹祖先树已经存在此包时, npm会拒绝安装

如果有A依赖BC, B依赖C, C依赖D的依赖关系, 那么将形成以下结构:
A
    –B
    –C
    –D

如果有A依赖BC, B依赖C和D@v1, C依赖D@v2, 那么形成的结构如下:
A
    –B
    –C
        --D@v2
    --D@v1

由于先安装的是B包, 所以D@v1便在顶层, 而C则要另外在C包内安装D@v2包, 可以看出, 如果安装顺序不同, 则树形结构也会是不一样的

以上