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![在这里插入图片描述](https://img-blog.csdnimg.cn/20210325203540515.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpbl9maWdodGlu,size_16,color_FFFFFF,t_70)
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属性对应的根目录。