webpack模块化原理 webpack打包的代码 允许我们使用各种模块化 如最常用的CommonJS  ES Module
CommonJS模块化实现原理; 使用commonjs 后 webpack打包好的bundle.js源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 var  __webpack_modules__ = {  "./src/js/format.js" :     (function  (module )  {       const  dateFormat = (date ) =>  {         return  "2020-12-12" ;       }       const  priceFormat = (price ) =>  {         return  "100.00" ;       }              module .exports = {         dateFormat,         priceFormat       }     }) } var  __webpack_module_cache__ = {};function  __webpack_require__ (moduleId )  {     if  (__webpack_module_cache__[moduleId]) {     return  __webpack_module_cache__[moduleId].exports;   }      var  module  = __webpack_module_cache__[moduleId] = { exports : {} };      __webpack_modules__[moduleId](module , module .exports, __webpack_require__);      return  module .exports; } !function  ( )  {      const  { dateFormat, priceFormat } = __webpack_require__("./src/js/format.js" );   console .log(dateFormat("abc" ));   console .log(priceFormat("abc" )); }(); 
 
ES Module模块化实现原理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 var  __webpack_modules__ = {  "./src/es_index.js" :     (function  (__unused_webpack_module, __webpack_exports__, __webpack_require__ )  {              __webpack_require__.r(__webpack_exports__);              var  _js_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/js/math.js" );       console .log(_js_math__WEBPACK_IMPORTED_MODULE_0__.mul(20 , 30 ));       console .log(_js_math__WEBPACK_IMPORTED_MODULE_0__.sum(20 , 30 ));     }),   "./src/js/math.js" :     (function  (__unused_webpack_module, __webpack_exports__, __webpack_require__ )  {       __webpack_require__.r(__webpack_exports__);                     __webpack_require__.d(__webpack_exports__, {         "sum" : function  ( )  { return  sum; },         "mul" : function  ( )  { return  mul; }       });       const  sum = (num1, num2 ) =>  {         return  num1 + num2;       }       const  mul = (num1, num2 ) =>  {         return  num1 * num2;       }     }) }; var  __webpack_module_cache__ = {};function  __webpack_require__ (moduleId )  {  if  (__webpack_module_cache__[moduleId]) {     return  __webpack_module_cache__[moduleId].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  });   }; }(); __webpack_require__("./src/es_index.js" ); 
 
ES Module 和 CommonJS相互调用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 var  __webpack_modules__ = ({  "./src/index.js" :     (function  (__unused_webpack_module, __webpack_exports__, __webpack_require__ )  {       "use strict" ;      __webpack_require__.r(__webpack_exports__);       var  _js_format__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/js/format.js" );       var  _js_format__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(_js_format__WEBPACK_IMPORTED_MODULE_0__);                     const  math = __webpack_require__("./src/js/math.js" );              console .log(math.sum(20 , 30 ));       console .log(math.mul(20 , 30 ));       console .log(_js_format__WEBPACK_IMPORTED_MODULE_0___default().dateFormat("aaa" ));       console .log(_js_format__WEBPACK_IMPORTED_MODULE_0___default().priceFormat("bbb" ));     }),   "./src/js/format.js" :     (function  (module )  {       const  dateFormat = (date ) =>  {         return  "2020-12-12" ;       }       const  priceFormat = (price ) =>  {         return  "100.00" ;       }       module .exports = {         dateFormat,         priceFormat       }     }),   "./src/js/math.js" :     (function  (__unused_webpack_module, __webpack_exports__, __webpack_require__ )  {              __webpack_require__.r(__webpack_exports__);       __webpack_require__.d(__webpack_exports__, {         "sum" : function  ( )  { return  sum; },         "mul" : function  ( )  { return  mul; }       });       const  sum = (num1, num2 ) =>  {         return  num1 + num2;       }       const  mul = (num1, num2 ) =>  {         return  num1 * num2;       }     }) }); var  __webpack_module_cache__ = {};function  __webpack_require__ (moduleId )  {     if  (__webpack_module_cache__[moduleId]) {     return  __webpack_module_cache__[moduleId].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  });   }; }(); __webpack_require__("./src/index.js" ); 
 
Source-map  当我们使用webpack打包时 在浏览器运行的代码是通过打包压缩的
真实跑在浏览器上的代码和我们编写的代码是有差异的 
Es6代码会转成ES5  对应的代码行号列号也会不同 
代码进行丑化压缩时, 会将编码名称修改 
 
当我们代码报错需要调试时 调试转换后的代码是很困难
 source-map  是从已转换的代码映射到原始的源文件
使浏览器可以重构原始源并在调试器中显示重建的原始源
 
source-map 的使用 使用source-map分为两个步骤
webpack.config.js中的devtool选项控制是否生成以及如何生成sourcemap
第一步:根据源文件,生成source-map文件,webpack在打包时,可以通过配置生成source-map;  
第二步:在转换后的代码,最后添加一个注释,它指向sourcemap;
//# sourceMappingURL=common.bundle.js.map 
 
 
 
浏览器会根据我们的注释,查找响应的source-map,并且根据source-map还原我们的代码,方便进行调试。
在chrome浏览器中 我们可以手动打开source-map(当然默认情况下是打开的
source-map的分析 目前的source-map长什么样子 
version:当前使用的版本,也就是最新的第三版;  
sources:从哪些文件转换过来的source-map和打包的代码(最初始的文件); 
names:转换前的变量和属性名称(因为我目前使用的是development模式,所以不需要保留转换前的名称); 
mappings:source-map用来和源文件映射的信息(比如位置信息等),一串base64 VLQ(veriablelength quantity可变长度值)编码; 
file:打包后的文件(浏览器加载的文件); 
sourceContent:转换前的具体代码信息(和sources是对应的关系); 
sourceRoot:所有的sources相对的根目录; 
 
MDN参考 https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/SourceMap.jsm 
生成source-map devtool有很多的选项处理source-map;  https://webpack.docschina.org/configuration/devtool/ 
选择不同的值生成的source-map会稍微有差异  打包过程也会有性能的差异 根据不同情况进行选择
不会生成source-map的值 
false: 不使用source-map,也就是没有任何和source-map相关的内容。 
 
none: production模式下的默认值,不生成source-map。 
 
eval: development模式下的默认值(什么值都不写),不生成source-map
但是它会在eval执行的代码中,添加 //# sourceURL=;  
它会被浏览器在执行时解析,并且在调试面板中生成对应的一些文件目录,方便我们调试代码; 
eval 的 效果