webpack编译结果分析
- 合并两个模块 ./src/a.js ./src/index.js
- 设置一个对象存放模块的路径和代码,key值对应的路径,value是函数,传入三个参数,module exports __webpack_require,其中exports是commjs的导出,modlue.exports
let modules = {
"./src/a.js": function (module, exports) {
eval("console.log(\"module a\")\nmodule.exports = \"a\";\n //# sourceURL=webpack:///./src/a.js")
},
"./src/index.js": function (module, exports, __webpack_require) {
eval("console.log(\"index module\")\nvar a = __webpack_require(\"./src/a.js\")\na.abc();\nconsole.log(a)\n //# sourceURL=webpack:///./src/index.js")
}
}
- 打包之后进行js模块化合并,采用立即执行函数,原因是避免定义全局变量进行污染,将上面定义的模块对象整体传入.
(function (modules) {
})({
"./src/a.js": function (module, exports) {
eval("console.log(\"module a\")\nmodule.exports = \"a\";\n //# sourceURL=webpack:///./src/a.js")
},
"./src/index.js": function (module, exports, __webpack_require) {
eval("console.log(\"index module\")\nvar a = __webpack_require(\"./src/a.js\")\na.abc();\nconsole.log(a)\n //# sourceURL=webpack:///./src/index.js")
}
});
- 立即执行函数体内部做如下两个操作:(1)定义__webpack_require函数定义参数:moduleId,根据moduleId拿到模块对象的执行函数进行执行,最后将模块的导出结果导出(2)执行./src/index.js的入口模块.
(function (modules) {
function __webpack_require(moduleId) {
var func = modules[moduleId];
var module = {
exports: {}
}
func(module, module.exports, __webpack_require);
var result = module.exports;
return result;
}
return __webpack_require("./src/index.js");
})({
"./src/a.js": function (module, exports) {
eval("console.log(\"module a\")\nmodule.exports = \"a\";\n //# sourceURL=webpack:///./src/a.js")
},
"./src/index.js": function (module, exports, __webpack_require) {
eval("console.log(\"index module\")\nvar a = __webpack_require(\"./src/a.js\")\na.abc();\nconsole.log(a)\n //# sourceURL=webpack:///./src/index.js")
}
});
- 设置模块导入缓存,避免重复导入同一个模块进行代码的反复执行
(function (modules) {
var moduleExports = {};
function __webpack_require(moduleId) {
if (moduleExports[moduleId]) {
return moduleExports[moduleId];
}
var func = modules[moduleId];
var module = {
exports: {}
}
func(module, module.exports, __webpack_require);
var result = module.exports;
moduleExports[moduleId] = result;
return result;
}
return __webpack_require("./src/index.js");
})({
"./src/a.js": function (module, exports) {
eval("console.log(\"module a\")\nmodule.exports = \"a\";\n //# sourceURL=webpack:///./src/a.js")
},
"./src/index.js": function (module, exports, __webpack_require) {
eval("console.log(\"index module\")\nvar a = __webpack_require(\"./src/a.js\")\na.abc();\nconsole.log(a)\n //# sourceURL=webpack:///./src/index.js")
}
});
模块对象的函数使用eval的原因
- 浏览器会将他放入单独的机制中进行执行,目的是为了方便调试,避免代码出错的时候在浏览器定位bug直接映射到打包之后的代码
//# sourceURL=webpack:///./src/a.js"
这段代码是为了在报错之后浏览器显示错误的时候更加清晰知道是哪个模块出的问题