1️⃣ 分析编译结果使用两个 a.js 模块和 index.js 模块

分析编译结果使用 CommonJS 模块化语法

a.js 模块
image.png
index.js 模块
image.png

1️⃣ 模拟 webpack 编译结果代码

  1. // 合并两个模块
  2. // - ./src/a.js
  3. // - ./src/index.js
  4. (function (modules) {
  5. var moduleExport = {}; // 用户缓存模块到导出结果
  6. function __webpack_require(moduleId) { // moduleId 就是模块路径
  7. if (moduleExport[moduleId]) {
  8. // 检查是否有缓存
  9. return moduleExport[moduleId]
  10. }
  11. var fun = modules[moduleId];
  12. var module = {
  13. export: {}
  14. };
  15. fun(module, module.exports, __webpack_require); // 运行模块
  16. var result = module.exports; // 得到模块的导出结果
  17. moduleExport[moduleId] = result;
  18. return result;
  19. };
  20. // 执行入口模块
  21. __webpack_require('./src/index.js') // require 函数相当于是运行一个模块, 的到模块导出的结果
  22. })({
  23. // 该对象保存了所有的模块, 以及模块对应的代码
  24. "./src/a.js": function (module, exports) {
  25. module.exports = function () {
  26. console.log('模块-A');
  27. }
  28. // webpack 的编译是放在 eval 中的
  29. // eval("module.exports = function () {\r\n console.log('模块-A');\r\n}\n\n//# sourceURL=webpack:///./src/a.js?");
  30. },
  31. "./src/index.js": function (module, exports, __webpack_require) {
  32. var a = __webpack_require("./src/a.js")
  33. console.log(a());
  34. console.log('模块-Index');
  35. // webpack 的编译是放在 eval 中的
  36. // eval("var a = __webpack_require__(/*! ./a */ \"./src/a.js\");\r\nconsole.log(a());\r\nconsole.log('模块-Index');\r\n\n\n//# sourceURL=webpack:///./src/index.js?");
  37. }
  38. })

1️⃣ webpack 编译结果代码

以下代码已经删减一些兼容其他模块化语法的代码

  1. (function (modules) {
  2. var installedModules = {};
  3. function __webpack_require__(moduleId) {
  4. if (installedModules[moduleId]) {
  5. return installedModules[moduleId].exports;
  6. }
  7. var module = installedModules[moduleId] = {
  8. i: moduleId,
  9. l: false,
  10. exports: {}
  11. };
  12. modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  13. module.l = true;
  14. return module.exports;
  15. }
  16. return __webpack_require__(__webpack_require__.s = "./src/index.js");
  17. })({
  18. "./src/a.js": (function (module, exports) {
  19. eval("module.exports = function () {\r\n console.log('模块-A');\r\n}\n\n//# sourceURL=webpack:///./src/a.js?");
  20. }),
  21. "./src/index.js": (function (module, exports, __webpack_require__) {
  22. eval("var a = __webpack_require__(/*! ./a */ \"./src/a.js\")\r\nconsole.log(a());\r\nconsole.log('模块-Index');\r\n\n\n//# sourceURL=webpack:///./src/index.js?");
  23. })
  24. });

1️⃣ webpack 中将代码放在 eval() 函数中执行的用意

将编译的代码写在 eval 中执行是为了精确报错信息 , 以下代码均以上部代码举例

2️⃣ 如果不写在 eval 中报错信息

image.png

2️⃣ 写在 eval 中的报错信息

浏览器会将 eval 函数中的内容当做一个独立的模块执行, 所以将代码写在 eval 函数中后 , 报错时只会显示报错的模块
image.png

2️⃣ eval 函数的末尾可以指定报错的文件名更容易找到报错的位置

image.png
上图中黄色框选中的内容是指定报错文件名的方式