单步调试理解 webpack 里通过 require 加载 nodejs 原生模块实现原理

在 webpack 和 nodejs 里,我们经常使用 require 函数加载原生模块或者开发人员自定义的模块。
原生模块的加载,比如:
const path = require("path");
这个语句是 webpack 和 nodejs 应用里经常使用到的。今天就来谈谈它的实现原理。
还是通过单步调试的方式来学习。
大家首先得通过我前一篇文章 webpack打包过程如何调试?学会如何调试 webpack 打包过程。
require 函数的实现位于 file:///internal/module.js

注意看第 10 行和第 13 行的 requireDepth 加减一。因为一个 module 通过 require 被加载时,可能会递归地加载另外的依赖 module,所以需要这个 requireDepth 字段来记录加载 module 的深度。
这个 module.js 的实际地址位于当前项目文件夹下的 node_modules 文件夹下面:

第 11 行的 mod 变量代表什么?
从调试器看出,就是当前命令行 node 启动的 webpack.js:

mod.require(path)会将执行投递到 Module._load 函数:

首先会去 Module._cache 里检查 path 模块是否已经加载了。在我这个例子里,path 是第一次加载,所以 Module._cache 是空的。

那么进入 NativeModule.require(filename):

nativeModule,即原生模块,里面也有 cache 缓存机制。

因为 path 模块显然是原生模块,而非开发人员自己定义的模块,因此 NativeModule.getCached 返回了已经被预加载的 path 模块.
cached.exports 里包含了一系列函数,这些函数就是我们 nodejs 应用里经常使用的工具函数,比如 join, parse, resolve 等等。

这就是 nodejs 和 webpack 里原生模块的加载原理。希望对前端开发人员有所帮助。

要获取更多 Jerry 的原创文章,请关注公众号"汪子熙".
版权声明: 本文为 InfoQ 作者【Jerry Wang】的原创文章。
原文链接:【http://xie.infoq.cn/article/fff36ed994fb649272e413b29】。文章转载请联系作者。
评论