探究 webpack 如何实现模块化加载
最近稍稍比较忙,但还是要腾出时间来写写博客,博客真的是个好东西,只要你坚持。这次主要讲讲 webpack 打包后的代码,分析他是如何实现模块化(同步)加载模块的,然后下次再讲讲如何按需(异步)加载模块。
一、webpack 模块化
关于模块化,可以看看我之前的总结博客 js模块化进程
总结一下,就是按照功能将一个项目切分成许多部分单独开发,然后再组装起来,每一个部分即为模块。
但是不管使用 require 还是 ES6 的 import ,最终都是经过 webpack 编译,模拟该行为,最后得到可执行代码。
二、webpack 同步加载源码
(1)源码
我们直接用一个例子展示,使用打包配置
module.exports = {
mode: "development",
devtool: "source-map",
...
}
主文件:
import func from './func.js'
func.add(1,2)
引用文件:
class func{
add(val1,val2){
return val1 + val2
}
}
export default new func()
打包后源码为:
(function (modules) { // 立刻执行函数 webpackBootstrap
var installedModules = {}; //缓存模块
function __webpack_require__(moduleId) { //模块加载函数
......
}
......
return __webpack_require__(__webpack_require__.s = "./src/index.js");
})({
({ //引用文件
"./src/func.js":
(function (module, __webpack_exports__, __webpack_require__) {
class func {
add(val1, val2) {
return val1 + val2
}
}
)}
__webpack_exports__["default"] = (new func());
}),
({ //主文件
"./src/index.js":
(function (module, __webpack_exports__, __webpack_require__) {
var _func_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/func.js");
_func_js__WEBPACK_IMPORTED_MODULE_0__["default"].add(1, 2)
})
});
1.使用了立刻执行函数的形式(webpackBootstrap),密闭空间。传入一个对象 modules ,以文件名为 key,value 是各个模块内的代码。
2.立刻执行函数内:
- installedModules 对象用于缓存模块
- _webpack_require_ 是一个模块加载函数,模拟 require 和 import
- 最后加载了主文件代码,主文件执行了 webpack_require 又引入了引用文件
(2)_webpack_require_ 如何实现模块加载
function __webpack_require__(moduleId) {
//使用缓存对象输出模块
if (installedModules[moduleId]) {
return installedModules[moduleId].exports;
}
//没有缓存则创建新模块
var module = installedModules[moduleId] = {
i: moduleId,
l: false,
exports: {}
};
//执行模块
modules[moduleId].call(module.exports, module,module.exports, __webpack_require__);
//模块加载完成标志
module.l = true;
//返回输出模块
return module.exports;
}
- 首先使用缓存看能否对象输出模块,缓存的目的其实就是加载时加速。
- 没有缓存则在对象内创建该模块,设置 i(模块ID),l(是否加载完成),exports(一个引用,指向模块的导出对象)
- 然后就是执行该模块,通过 call 把 this 绑定在输出模块内。
同时观察一下引用文件,它是通过 export 输出内容的,而 export 正就是传入该模块的第三个参数 module.export。并且上述函数绑定的执行环境也是这个输出模块。通过相互循环引用,达成了拆分文件模块后,调用时执行环境不变的效果。
当然,webpack 远不止做了这些操作,本次只讲了一个简化的主流程。方便大家理解这个过程。

本文探讨了webpack如何实现模块化加载,从webpack模块化的概念到同步加载的源码解析,详细介绍了_webpack_require_函数在模块加载中的作用,帮助读者理解webpack编译后的代码如何确保模块的正确执行。
1625

被折叠的 条评论
为什么被折叠?



