webpack模塊化打包源碼淺讀

要閱讀webpack打包后的代碼,要在webpack配置文件中設(shè)置

mode: 'development', // 默認(rèn)為 production,會(huì)對(duì)代碼進(jìn)行壓縮丑化,不利于閱讀
devtool: 'source-map'  // 開(kāi)發(fā)環(huán)境下默認(rèn)為 'eval' ,部分代碼會(huì)被 eval 函數(shù)包裹,不利于閱讀,eval包裹函數(shù)的目的是還原報(bào)錯(cuò)信息

1.CommonJS 打包后源碼解讀

// 定義了一個(gè)對(duì)象
// 模塊的路徑作為 key,函數(shù)作為 value
var __webpack_modules__ = ({
  "./src/js/formate.js":
    (function (module) {

      const dateFormate = (date) => {
        return '2020-12-12';
      }

      const priceFormate = (price) => {
        return '100.00';
      }

      // 對(duì) __webpack_require__ 函數(shù)的 module 對(duì)象的 exports屬性進(jìn)行賦值
      module.exports = {
        dateFormate,
        priceFormate
      }
    })
});

  // 定義一個(gè)對(duì)象,用于加載模塊的緩存
  var __webpack_module_cache__ = {};

  // 是一個(gè)函數(shù),當(dāng)我們加載一個(gè)模塊時(shí),都會(huì)通過(guò)這個(gè)函數(shù)來(lái)加載
  function __webpack_require__(moduleId) {
    /** 1.判斷緩存中是否已加載過(guò) */
    var cachedModule = __webpack_module_cache__[moduleId]; 
    if (cachedModule !== undefined) { // 緩存已加載過(guò)
      return cachedModule.exports;
    }

    /**2.
     * 對(duì)象的連續(xù)賦值,這里是把模塊添加進(jìn)緩存,并賦值給 module ,賦值了同一個(gè)對(duì)象
     * 這里 module 和  __webpack_module_cache__[moduleId] 指向同一個(gè)內(nèi)存地址,更改一個(gè),另一個(gè)也會(huì)被更改
     **/
    var module = __webpack_module_cache__[moduleId] = { 
      exports: {}
    };

    /** 3.開(kāi)始加載執(zhí)行模塊 */
    __webpack_modules__[moduleId](module, module.exports, __webpack_require__);

    return module.exports; // 返回了一個(gè)賦值后的對(duì)象
  }

  var __webpack_exports__ = {};

  // 具體執(zhí)行代碼
  !function () {
    const { dateFormate, priceFormate } = __webpack_require__("./src/js/formate.js"); // 執(zhí)行上面的加載函數(shù),解構(gòu)拿到數(shù)據(jù)

    console.log(dateFormate('abc'));
    console.log(priceFormate('abc'));
  }();

2. ES Module 打包后源碼解讀

// ESModule 相比 CommonJS,多做了一層代理,做了代理之后一些語(yǔ)法就能刻意的不被允許

// 定義了一個(gè)對(duì)象——模塊映射
var __webpack_modules__ = ({
  "./src/js/math.js":
    (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {

      __webpack_require__.r(__webpack_exports__); // 調(diào)用 r 的目的是記錄是一個(gè) ESModule:__esModule:true
      
      // 調(diào)用 d 的目的是:給 exports 設(shè)置代理為 definition
      // exports 對(duì)象中本身沒(méi)有對(duì)應(yīng)的函數(shù),只有調(diào)用 get 的時(shí)候去取
      __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;
      }
    })
});

// webpack 模塊緩存
var __webpack_module_cache__ = {};

// require函數(shù)的實(shí)現(xiàn)
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__ 函數(shù)對(duì)象添加一個(gè)屬性:d,值是一個(gè)函數(shù)
  __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__ 函數(shù)對(duì)象添加一個(gè)屬性:o,值是一個(gè)函數(shù),判斷是否有該屬性
  __webpack_require__.o = function (obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
}();

!function () {
  // 給 __webpack_require__ 函數(shù)對(duì)象添加一個(gè)屬性:r,值是一個(gè)函數(shù)
  __webpack_require__.r = function (exports) {
    if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { // 判斷是否支持 Symbol
      Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); // 增加一個(gè) Symbol.toStringTag 屬性,表示是一個(gè)模塊
    }
    Object.defineProperty(exports, '__esModule', { value: true }); // 在 exports 對(duì)象中增加一個(gè) __esModule 屬性,值為 true,記錄是一個(gè) ESModule
  };
}();

var __webpack_exports__ = {};
!function () {
  var _js_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/js/math.js");

  // 調(diào)用代理
  console.log((0, _js_math__WEBPACK_IMPORTED_MODULE_0__.mul)(20, 30))
  console.log((0, _js_math__WEBPACK_IMPORTED_MODULE_0__.sum)(20, 30))
}();

3.CommonJS 和 ESModule 相互導(dǎo)入

var __webpack_modules__ = ({

  "./src/js/formate.js": (function (module) {

    const dateFormate = (date) => {
      return '2020-12-12';
    }

    const priceFormate = (price) => {
      return '100.00';
    }

    module.exports = {
      dateFormate,
      priceFormate
    }

  }),
  "./src/js/math.js": (function (__unused_webpack_module, __webpack_exports__, __webpack_require__) {

    "use strict";
    __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) {
  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__);
  var _js_formate__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/js/formate.js");
  var _js_formate__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(_js_formate__WEBPACK_IMPORTED_MODULE_0__);

  const math = __webpack_require__("./src/js/math.js");
  console.log(math.mul(20, 30))
  console.log(math.sum(20, 30))



  console.log(_js_formate__WEBPACK_IMPORTED_MODULE_0___default().dateFormate('abc'))
  console.log(_js_formate__WEBPACK_IMPORTED_MODULE_0___default().priceFormate('abc'))
}();
;

4.總結(jié),webpack如何對(duì)模塊化進(jìn)行支持?

webpack 封裝了多個(gè)函數(shù),并把一個(gè)個(gè)模塊放到了對(duì)象里面進(jìn)行管理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容