// 源文件
// 文件 entry.js
const { add } = require("./add");
add(1, 2);
console.log("hello world");
// 文件 add.js
function add(a, b) {
console.log(a + b);
return a + b;
}
module.exports = {
add,
};
复制代码
1. 整体结构:立即执行函数
(function(modules){})({})
复制代码
2. 立即执行函数的实参部分:{}
- 以文件相对于根目录的路径为key,文件内容为value
- value都是匿名的函数表达式,该函数会接受三个参数
// 包装函数
(function(module, exports, __webpack_require__){
// 文件内容
})
复制代码
⁉️ module
, exports
, __webpack_require__
都是什么?
3. 立即执行函数内部逻辑
3.1 整体结构
var installedModules = {}
function __webpack_require__(moduleId){}
// 下面这些赋值 当前都么有用
__webpack_require__.m = modules
__webpack_require__.c = installedModules;
__webpack_require__.d = function(exports, name, getter) {}
__webpack_require__.r = function(exports) {}
__webpack_require__.t = function(value, mode) {}
__webpack_require__.n = function(module) {}
__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
__webpack_require__.p = "";
__webpack_require__.s = "./playground/entry.js"
return __webpack_require__("./playground/entry.js")
复制代码
3.2 function _webpack_require__('./playground/entry.js')
// 1. 如果moduleId已缓存在installedModules中,直接返回缓存模块的exports属性
// 2. 没有缓存的话, 新建一个module,同时注入到installedModules中
// 新module有三个属性
var module = installedModules['./playground/entry.js'] = {
i: './playground/entry.js',
l: false, // loaded
exports: {}
}
// 3. modules[moduleId] --> (function(){ 对应moduleId的文件内容 })
// 所以这里就能看到上面的 module, module.exports, __webpack_require__ 分别指什么
// module指当前模块,是一个对象 有三个属性
// module.export 也是一个对象 内部 module.export = {} 都会注入到该对象里,也会在installedModule中缓存下来
// __webpack_require__ 是文件引用的函数,他能通过文件名,找到对应的模块暴露出来的数据
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__))
// 上面执行完之后 installedModules['./playground/entry.js'] 也被注入了moduleId对应模块导出的信息,将loaded置为true,表明当前模块以及加载完成
module.l = true
// 返回当前模块的导出内容
return module.exports
复制代码
所以到这里主要思路是:
- 首先会根据依赖树将所有文件处理生成一个对象,对象的每一项都是 文件路径 + 被函数包装的文件内容
- 整体是一个立即执行函数,函数体内定义了模块解析函数
__webpack_require__
, 然后开始执行__webpack_require__(入口模块路径)
__webpack_require__
解析模块时,通过文件路径去步骤1
中的对象中寻找对应的包装函数,包装函数里有该路径对应的文件的完整内容- 执行包装函数,即执行文件内容,包装函数内部通过实参的引用的方式将内部的数据导出到外部,并缓存到
installedModules
中
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END