60 - 《找到依赖:node 和 webpack 的 resolve 机制》

发布于 2022年2月23日

工程化小册试写章节。昨晚看 XYG 和 EStar 比赛占据太多时间,没来不及更完。。

现在基本都是模块化开发,理解「如何找到依赖」是一个很基础的知识点。但以我的接触来看,很多同学并不清楚 resolve 机制,包括很多资深的同学,然后会乱用,虽然当下能跑,但却是在给未来的自己、同事和产品留坑。

举个例子。比如一个项目,package.json 中声明 dependencies: { "foo": "1" },然后 foo 依赖 bar,这时开发者想用 bar 应该怎么办?

A、require('foo/node_modules/bar')
B、require('bar'),因为用 npm 安装 foo 后,bar 被提取到 node_modules 根目录了
C、package.json 添加依赖 bar,然后 require('bar')

答案是 C。为啥 A 和 B 不行?背后原因是相同的,因为 bar 不一定出现在现在的位置。

上面的例子,通过 npm install 之后,node_modules 的结构可能是,

+ node_modules
  + foo
    + node_modules
      + bar

也可能是,

+ node_modules
  + foo
  + bar

这会受其他依赖影响,比如除了 foo 依赖 bar,项目还依赖了 B,B 也依赖了相同版本的 bar,就会是上述后者的目录结构,bar 被提取到顶层,这样设计的目的是为了避免重复。但如果又依赖了 C,C 依赖了不同版本的 bar,结构又会有变化,具体这部分我们会在 npm client 章节展开,比如典型的 Phantom dependencies 和 NPM doppelgangers 问题等。

大家可以记住一个规则,「不管是项目还是 npm 依赖,只 require 或 require.resolve 或 import 当前 package.json 的 dependencies 中声明过的依赖」。

p.s. 推荐大家用 pnpm,引用错误时会显式抛错,因为 pnpm 安装依赖后,node_modules 下只会有 package.json 中声明过的依赖。

看完例子,下面我们分 Node 的 resolve 规则和 webpack 的 reso

内容预览已结束

此内容需要会员权限。请先登录以查看完整内容。