webpack5 基础配置(4下)模块化原理 && 初识source map

3 commonjs引用esmodule

前面我们讲了webpack实现模块化得原理,分别是commonjs esmodule,现在讲一下commonjs引用esmodue。先看例子
在这里插入图片描述
esmodule导出
在这里插入图片描述
commonjs引入。打包成功,正常显示
在这里插入图片描述
看下源码。

var __webpack_modules__ = {
  "./src/js/main.js": function (
    __unused_webpack_module,
    __webpack_exports__,
    __webpack_require__
  ) {
    "use strict";
    __webpack_require__.r(__webpack_exports__);
    __webpack_require__.d(__webpack_exports__, {
      num: function () {
        return /* binding */ num;
      },
      num2: function () {
        return /* binding */ num2;
      },
    });
    const num = (num1, num2) => {
      return num1 + num2;
    };

    const num2 = 2;

    /***/
  },
};
var __webpack_module_cache__ = {};

function __webpack_require__(moduleId) {
  var cachedModule = __webpack_module_cache__[moduleId];
  if (cachedModule !== undefined) {
    return cachedModule.exports;
  }
  var module = (__webpack_module_cache__[moduleId] = {
    exports: {},
  });

  __webpack_modules__[moduleId](module, module.exports, __webpack_require__);

  return module.exports;
}

!(function () {
  __webpack_require__.d = function (exports, definition) {
    for (var key in definition) {
      if (
        __webpack_require__.o(definition, key) &&
        !__webpack_require__.o(exports, key)
      ) {
        Object.defineProperty(exports, key, {
          enumerable: true,
          get: definition[key],
        });
      }
    }
  };
})();

!(function () {
  __webpack_require__.o = function (obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
  };
})();

!(function () {
  __webpack_require__.r = function (exports) {
    if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
      Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
    }
    Object.defineProperty(exports, "__esModule", { value: true });
  };
})();
var __webpack_exports__ = {};
!(function () {
  const { num, num2 } = __webpack_require__(
    /*! ./js/main */ "./src/js/main.js"
  );
  console.log(num(1, 2));
  console.log(num2);
})();

一看代码,这不是跟我们的esmodule一样吗。给webpack-require加上三个属性,d o r,分别做对应的事情。唯一不一样就是
在这里插入图片描述
立刻执行函数这里,少了给我们的对象webpack-module加上标记,因为我们不是esmodule导出的,是commonjs导出的。

看看第四种,esmodue引用commonjs在这里插入图片描述

commonjs导出
在这里插入图片描述
esmoduel引入
打包后看看

var __webpack_modules__ = {
  "./src/js/main.js": function (module) {
    const num = (num1, num2) => {
      return num1 + num2;
    };
    const num2 = 2;
      module.exports = {
      num,
      num2,
    };
  },
};
var __webpack_module_cache__ = {};
function __webpack_require__(moduleId) {
  var cachedModule = __webpack_module_cache__[moduleId];
  if (cachedModule !== undefined) {
    return cachedModule.exports;
  }
  var module = (__webpack_module_cache__[moduleId] = {
    exports: {},
  });

  __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
  return module.exports;
}

!(function () {
  __webpack_require__.n = function (module) {
    var getter =
      module && module.__esModule
        ? function () {
            return module["default"];
          }
        : function () {
            return module;
          };
    __webpack_require__.d(getter, { a: getter });
    return getter;
  };
})();

!(function () {
  __webpack_require__.d = function (exports, definition) {
    for (var key in definition) {
      if (
        __webpack_require__.o(definition, key) &&
        !__webpack_require__.o(exports, key)
      ) {
        Object.defineProperty(exports, key, {
          enumerable: true,
          get: definition[key],
        });
      }
    }
  };
})();
!(function () {
  __webpack_require__.o = function (obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
  };
})();
!(function () {
  __webpack_require__.r = function (exports) {
    if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
      Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
    }
    Object.defineProperty(exports, "__esModule", { value: true });
  };
})();

var __webpack_exports__ = {};
!(function () {
  "use strict";
  __webpack_require__.r(__webpack_exports__);
  /* harmony import */ var _js_main__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
    /*! ./js/main */ "./src/js/main.js"
  );
  /* harmony import */ var _js_main__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(
    _js_main__WEBPACK_IMPORTED_MODULE_0__
  );

  console.log((0, _js_main__WEBPACK_IMPORTED_MODULE_0__.num)(1, 2));
  console.log(_js_main__WEBPACK_IMPORTED_MODULE_0__.num2);
})();

这里的话差别可能有点大了。
一步一步看
在这里插入图片描述
对象还是那个老对象,然后给exports赋值是直接赋值,不是通过d函数。
在这里插入图片描述
这里又给他打标记了,表示我们的esmodule引用。其他的主要新增了
在这里插入图片描述
n函数,这个函数时判断是不是esmodule,是的话就返回Module['default‘],不是的话就返回module,然后通过d将属性代理到getter也就是我们的module或者module[‘default’],然后返回,其实这个没用到 o d n r函数,r函数用了做标记。一开始的时候标记这个Module,所以我们姑且不管。那其实也很简单了。看多几遍就懂了。

再看看一个复杂点的

common导出在这里插入图片描述
eSmodule导出
在这里插入图片描述
在这里插入图片描述
互相导入,看源码

var __webpack_modules__ = {
  /***/ "./src/js/format.js": /***/ function (
    __unused_webpack_module,
    __webpack_exports__,
    __webpack_require__
  ) {
    "use strict";
    __webpack_require__.r(__webpack_exports__);
    /* harmony export */ __webpack_require__.d(__webpack_exports__, {
      /* harmony export */ num3: function () {
        return /* binding */ num3;
      },
      /* harmony export */ num4: function () {
        return /* binding */ num4;
      },
      /* harmony export */
    });
    const num3 = () => {
      console.log("123");
    };
    const num4 = () => {
      console.log(num4);
    };

    /***/
  },

  /***/ "./src/js/main.js":
    /*!************************!*\
  !*** ./src/js/main.js ***!
  \************************/
    /***/ function (module) {
      const num = (num1, num2) => {
        return num1 + num2;
      };

      const num2 = 2;

      module.exports = {
        num,
        num2,
      };

      /***/
    },
};
/************************************************************************/
// The module cache
var __webpack_module_cache__ = {};

// The require function
function __webpack_require__(moduleId) {
  // Check if module is in cache
  var cachedModule = __webpack_module_cache__[moduleId];
  if (cachedModule !== undefined) {
    return cachedModule.exports;
  }
  var module = (__webpack_module_cache__[moduleId] = {
    exports: {},
  });

  __webpack_modules__[moduleId](module, module.exports, __webpack_require__);

  return module.exports;
}

!(function () {
  __webpack_require__.n = function (module) {
    var getter =
      module && module.__esModule
        ? function () {
            return module["default"];
          }
        : function () {
            return module;
          };
    __webpack_require__.d(getter, { a: getter });
    return getter;
  };
})();

!(function () {
  __webpack_require__.d = function (exports, definition) {
    for (var key in definition) {
      if (
        __webpack_require__.o(definition, key) &&
        !__webpack_require__.o(exports, key)
      ) {
        Object.defineProperty(exports, key, {
          enumerable: true,
          get: definition[key],
        });
      }
    }
  };
})();

/* webpack/runtime/hasOwnProperty shorthand */
!(function () {
  __webpack_require__.o = function (obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
  };
})();

/* webpack/runtime/make namespace object */
!(function () {
  // define __esModule on exports
  __webpack_require__.r = function (exports) {
    if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
      Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
    }
    Object.defineProperty(exports, "__esModule", { value: true });
  };
})();

/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
!(function () {
  "use strict";

  __webpack_require__.r(__webpack_exports__);
  /* harmony import */ var _js_main__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
    /*! ./js/main */ "./src/js/main.js"
  );
  /* harmony import */ var _js_main__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(
    _js_main__WEBPACK_IMPORTED_MODULE_0__
  );

  const { num3, num4 } = __webpack_require__(
    /*! ./js/format */ "./src/js/format.js"
  );
  console.log((0, _js_main__WEBPACK_IMPORTED_MODULE_0__.num)(1, 2));
  console.log(_js_main__WEBPACK_IMPORTED_MODULE_0__.num2);
  num3();
  num4();
})();

一步一步看,首先创建的对象

var __webpack_modules__ = {
  /***/ "./src/js/format.js": /***/ function (
    __unused_webpack_module,
    __webpack_exports__,
    __webpack_require__
  ) {
    "use strict";
    __webpack_require__.r(__webpack_exports__);
    __webpack_require__.d(__webpack_exports__, {
      /* harmony export */ num3: function () {
        return /* binding */ num3;
      },
      /* harmony export */ num4: function () {
        return /* binding */ num4;
      },
      /* harmony export */
    });
    const num3 = () => {
      console.log("123");
    };
    const num4 = () => {
      console.log(num4);
    };

    /***/
  },
  /***/ "./src/js/main.js":
    /***/ function (module) {
      const num = (num1, num2) => {
        return num1 + num2;
      };

      const num2 = 2;

      module.exports = {
        num,
        num2,
      };

      /***/
    },
};

因为我们有两个导入,所以有两个对象,分别对应esmodule导出和commonjs导出,可以看到两者对exports对象的处理还是不一眼的,commonjs导出是直接赋值,而esmodule导出是做了代理设置。
在这里插入图片描述
看立即调用函数如何执行代码。
可以看到num3,num4是可以进行解构导入的,也就是说commonjs的导入是可以解构的,按我的理解,不知道正不正确,就是commonjs的导入远离其实是对一个对象的拷贝,然后我们可以赋值解构这个对象。然后如图,num1,num2是对应improt导入的,虽然我们在写的时候在这里插入图片描述

总结: 可以看到,common。js导出是通过值得拷贝,他是直接将值赋予到exports上的。而import导出是通过代理,也就是值得引用。这也是common与import的区别。

认识source map

什么是source map呢。我们平常运行在浏览器的代码是经过打包压缩的,如es6->es5等。如果我们打包完运行,然后浏览器报错了,那我们很难确定报错在哪里报错。

在这里插入图片描述
在这里插入图片描述

去掉soure-map,,mode改为procution在这里插入图片描述在这里插入图片描述
鬼知道是哪里发生错误了。所以就需要source-map。

socure map是从已转换的代码,映射到原始的源文件,使浏览器可以重构原始源并在调试器中显示重建得原始源;

如何使用source-map

1 根据源文件,生成sourcr-map文件,webpack打包时,可以通过配置生成source-map
2 在转换后的代码添加注射,指向source-map
在这里插入图片描述
看看效果
在这里插入图片描述
已经生成soruce-map文件了
在这里插入图片描述
注释指向source-map文件。在这里插入图片描述
在这里插入图片描述
可以看到,浏览器可以根据我们的Bundle和source-map文件映射到源文件去,一下子就发现错误。在这里插入图片描述
浏览器已经帮我们还原出来源文件了。在这里插入图片描述
浏览器这里可以判断值不支持source-map。

source-map第一版出来的时候,大小是源文件的十倍,第二版减少了50%,第三版又减少50%,所以目前一个133kb的文件,最终的source-map的大小只有330kb。
所以我们一般在开发阶段,测试阶段,发布阶段用的source-map是不一样的。

source-map文件

{
    "version": 3,
    "sources": [
        "webpack://t/./src/js/format.js",
        "webpack://t/./src/js/main.js",
        "webpack://t/webpack/bootstrap",
        "webpack://t/webpack/runtime/compat get default export",
        "webpack://t/webpack/runtime/define property getters",
        "webpack://t/webpack/runtime/hasOwnProperty shorthand",
        "webpack://t/webpack/runtime/make namespace object",
        "webpack://t/./src/index.js"
    ],
    "names": [
        "num3",
        "console",
        "log",
        "num4",
        "module",
        "exports",
        "num",
        "num1",
        "num2",
        "__webpack_module_cache__",
        "__webpack_require__",
        "moduleId",
        "cachedModule",
        "undefined",
        "__webpack_modules__",
        "n",
        "getter",
        "__esModule",
        "d",
        "a",
        "definition",
        "key",
        "o",
        "Object",
        "defineProperty",
        "enumerable",
        "get",
        "obj",
        "prop",
        "prototype",
        "hasOwnProperty",
        "call",
        "r",
        "Symbol",
        "toStringTag",
        "value",
        "asdasd"
    ],
    "mappings": "wHAAA,MAAMA,EAAO,KACTC,QAAQC,IAAI,QAEVC,EAAO,KACTF,QAAQC,IAAIC,K,gBCEhBC,EAAOC,QAAU,CACbC,IAPQ,CAACC,EAAMC,IACRD,EAAOC,EAMTA,KAHI,KCHTC,EAA2B,GAG/B,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBE,IAAjBD,EACH,OAAOA,EAAaP,QAGrB,IAAID,EAASK,EAAyBE,GAAY,CAGjDN,QAAS,IAOV,OAHAS,EAAoBH,GAAUP,EAAQA,EAAOC,QAASK,GAG/CN,EAAOC,QCpBfK,EAAoBK,EAAI,SAASX,GAChC,IAAIY,EAASZ,GAAUA,EAAOa,WAC7B,WAAa,OAAOb,EAAgB,SACpC,WAAa,OAAOA,GAErB,OADAM,EAAoBQ,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,GCLRN,EAAoBQ,EAAI,SAASb,EAASe,GACzC,IAAI,IAAIC,KAAOD,EACXV,EAAoBY,EAAEF,EAAYC,KAASX,EAAoBY,EAAEjB,EAASgB,IAC5EE,OAAOC,eAAenB,EAASgB,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,MCJ3EX,EAAoBY,EAAI,SAASK,EAAKC,GAAQ,OAAOL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,ICC/FlB,EAAoBsB,EAAI,SAAS3B,GACX,oBAAX4B,QAA0BA,OAAOC,aAC1CX,OAAOC,eAAenB,EAAS4B,OAAOC,YAAa,CAAEC,MAAO,WAE7DZ,OAAOC,eAAenB,EAAS,aAAc,CAAE8B,OAAO,K,qCCJvD,MAAM,KAAEnC,EAAI,KAAEG,GAAS,EAAQ,KAC/BF,QAAQC,KAAI,IAAAI,KAAI,EAAE,IAClBL,QAAQC,IAAI,EAAAM,MACZR,IACAG,IACAF,QAAQC,IAAIkC,Q",
    "file": "js/bundle.js",
    "sourcesContent": [
        "const num3 = ()=>{\r\n    console.log('123');\r\n}\r\nconst num4 = () => {\r\n    console.log(num4);\r\n}\r\nexport {\r\n    num3, num4\r\n}",
        "const num = (num1, num2)=>{\r\n    return num1 + num2\r\n}\r\n\r\nconst num2 = 2\r\n\r\nmodule.exports = {\r\n    num, num2\r\n}",
        "// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n",
        "// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};",
        "// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};",
        "__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }",
        "// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};",
        "import { num, num2 } from './js/main'\r\nconst { num3, num4 } = require('./js/format')\r\nconsole.log(num(1,2));\r\nconsole.log(num2);\r\nnum3()\r\nnum4()\r\nconsole.log(asdasd);"
    ],
    "sourceRoot": ""
}

在这里插入图片描述
version第三版本,source,源文件。从那些源文件加载出来的。names属性,这些是转换之前的名称
在这里插入图片描述
如果不需要转换,即不需要打包,names为空。
mappings核心:这个东西是经过base64VSQ编码。记录着很多信息,根据这个信息加上Bundle.js文件找到源代码。
在这里插入图片描述
接下来几个属性都比较明显了
在这里插入图片描述
文件路径,bundle.js以及sourceRoot则是我们的source属性对应的根目录。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coderlin_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值