webpack模組化學習記錄

鬧鬧不愛鬧發表於2019-02-02

webpack打包之後的bundle.js其實是一個立即執行函式,類似:複製程式碼

(function(modules){
     const initModules = {}; // 載入過的module都會在這裡快取        
    // 關鍵點就是定義了require載入函式,每次import或者require的時候就會呼叫自定義的這個require函式
    __webpack__require__ = function(moduleId) {
        // 如果模組載入過,直接返回快取中的內容
        if (initModules[moduleId]) return initModules[moduleId].exports;
        const module = initModules[moduleId] = { // 模擬commonJs的module物件
            exports: {}    
        };
        // 重點:將this指向module.exports執行對應moduleId對應的包裝函式,並且將module,module.exports,__require__作為引數
        modules[moduleId].call(module.exports, module, module.exports, __webpack__require__);
        return module.exports; // 將已經作為引數的module.exports返回。
    };
    
    // 用於等非同步載入,替代import()去載入模組。原理就是建立script標籤
    __webpack__require.e = function(){ // 簡化程式碼
        const script = document.createElement('script');
        script.src = jsonScriptSrc(chunkId); // 生成src地址
        document.head.appendChind(script); // 將scriptpush到head標籤中
    }
    __webpack_require__.p = `${output.publicPath}`; // 根據output.publicPath動態生成複製程式碼
    function jsonScriptSrc(chunkId) {
        // 根據output.publicPath和chunkFilename生成最終的src。
        return __webpack__require__.p + `${chunkFilename}`; // 虛擬碼,基本就這麼個意思,原始碼看最上面複製程式碼
    }
})([
    // modules就是由包裝過後的模組程式碼組成
    function(module, exports, require) {
        // 引數:module就是在上面定義的module物件; require就是__webpack__require__函式
    },
    function(module, exports, require) {
        // 引數:module就是在上面定義的module物件; require就是__webpack__require__函式
    }
])複製程式碼

多說一點:

output.publicPath就是為程式碼中靜態資源的引入新增一個路徑字首,如果你的靜態資源是放在CDN上的,可以寫成絕對路徑;如果是放在本地伺服器的,則需要寫一個相對於html檔案的相對路徑。

devServer.publicPath:必須是/開頭和/結尾,表示相對於當前服務路徑的地址.

參考原始碼:

/******/ (function(modules) { // webpackBootstrap/******/  // install a JSONP callback for chunk loading/******/  function webpackJsonpCallback(data) {/******/    var chunkIds = data[0];/******/    var moreModules = data[1];/******/    var executeModules = data[2];/******//******/    // add "moreModules" to the modules object,/******/    // then flag all "chunkIds" as loaded and fire callback/******/    var moduleId, chunkId, i = 0, resolves = [];/******/    for(;i < chunkIds.length; i++) {/******/      chunkId = chunkIds[i];/******/      if(installedChunks[chunkId]) {/******/        resolves.push(installedChunks[chunkId][0]);/******/      }/******/      installedChunks[chunkId] = 0;/******/    }/******/    for(moduleId in moreModules) {/******/      if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {/******/        modules[moduleId] = moreModules[moduleId];/******/      }/******/    }/******/    if(parentJsonpFunction) parentJsonpFunction(data);/******//******/    while(resolves.length) {/******/      resolves.shift()();/******/    }/******//******/    // add entry modules from loaded chunk to deferred list/******/    deferredModules.push.apply(deferredModules, executeModules || []);/******//******/    // run deferred modules when all chunks ready/******/    return checkDeferredModules();/******/  };/******/  function checkDeferredModules() {/******/    var result;/******/    for(var i = 0; i < deferredModules.length; i++) {/******/      var deferredModule = deferredModules[i];/******/      var fulfilled = true;/******/      for(var j = 1; j < deferredModule.length; j++) {/******/        var depId = deferredModule[j];/******/        if(installedChunks[depId] !== 0) fulfilled = false;/******/      }/******/      if(fulfilled) {/******/        deferredModules.splice(i--, 1);/******/        result = __webpack_require__(__webpack_require__.s = deferredModule[0]);/******/      }/******/    }/******/    return result;/******/  }/******//******/  // The module cache/******/  var installedModules = {};/******//******/  // object to store loaded and loading chunks/******/  // undefined = chunk not loaded, null = chunk preloaded/prefetched/******/  // Promise = chunk loading, 0 = chunk loaded/******/  var installedChunks = {/******/    "main": 0/******/  };/******//******/  var deferredModules = [];/******//******/  // script path function/******/  function jsonpScriptSrc(chunkId) {/******/    return __webpack_require__.p + "" + ({"home":"home","user":"user"}[chunkId]||chunkId) + ".bundle.js"/******/  }/******//******/  // The require function/******/  function __webpack_require__(moduleId) {/******//******/    // Check if module is in cache/******/    if(installedModules[moduleId]) {/******/      return installedModules[moduleId].exports;/******/    }/******/    // Create a new module (and put it into the cache)/******/    var module = installedModules[moduleId] = {/******/      i: moduleId,/******/      l: false,/******/      exports: {}/******/    };/******//******/    // Execute the module function/******/    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);/******//******/    // Flag the module as loaded/******/    module.l = true;/******//******/    // Return the exports of the module/******/    return module.exports;/******/  }/******//******/  // This file contains only the entry chunk./******/  // The chunk loading function for additional chunks/******/  __webpack_require__.e = function requireEnsure(chunkId) {/******/    var promises = [];/******//******//******/    // JSONP chunk loading for javascript/******//******/    var installedChunkData = installedChunks[chunkId];/******/    if(installedChunkData !== 0) { // 0 means "already installed"./******//******/      // a Promise means "currently loading"./******/      if(installedChunkData) {/******/        promises.push(installedChunkData[2]);/******/      } else {/******/        // setup Promise in chunk cache/******/        var promise = new Promise(function(resolve, reject) {/******/          installedChunkData = installedChunks[chunkId] = [resolve, reject];/******/        });/******/        promises.push(installedChunkData[2] = promise);/******//******/        // start chunk loading/******/        var script = document.createElement('script');/******/        var onScriptComplete;/******//******/        script.charset = 'utf-8';/******/        script.timeout = 120;/******/        if (__webpack_require__.nc) {/******/          script.setAttribute("nonce", __webpack_require__.nc);/******/        }/******/        script.src = jsonpScriptSrc(chunkId);/******//******/        onScriptComplete = function (event) {/******/          // avoid mem leaks in IE./******/          script.onerror = script.onload = null;/******/          clearTimeout(timeout);/******/          var chunk = installedChunks[chunkId];/******/          if(chunk !== 0) {/******/            if(chunk) {/******/              var errorType = event && (event.type === 'load' ? 'missing' : event.type);/******/              var realSrc = event && event.target && event.target.src;/******/              var error = new Error('Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')');/******/              error.type = errorType;/******/              error.request = realSrc;/******/              chunk[1](error);/******/            }/******/            installedChunks[chunkId] = undefined;/******/          }/******/        };/******/        var timeout = setTimeout(function(){/******/          onScriptComplete({ type: 'timeout', target: script });/******/        }, 120000);/******/        script.onerror = script.onload = onScriptComplete;/******/        document.head.appendChild(script);/******/      }/******/    }/******/    return Promise.all(promises);/******/  };/******//******/  // expose the modules object (__webpack_modules__)/******/  __webpack_require__.m = modules;/******//******/  // expose the module cache/******/  __webpack_require__.c = installedModules;/******//******/  // define getter function for harmony exports/******/  __webpack_require__.d = function(exports, name, getter) {/******/    if(!__webpack_require__.o(exports, name)) {/******/      Object.defineProperty(exports, name, { enumerable: true, get: getter });/******/    }/******/  };/******//******/  // 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 });/******/  };/******//******/  // create a fake namespace object/******/  // mode & 1: value is a module id, require it/******/  // mode & 2: merge all properties of value into the ns/******/  // mode & 4: return value when already ns object/******/  // mode & 8|1: behave like require/******/  __webpack_require__.t = function(value, mode) {/******/    if(mode & 1) value = __webpack_require__(value);/******/    if(mode & 8) return value;/******/    if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;/******/    var ns = Object.create(null);/******/    __webpack_require__.r(ns);/******/    Object.defineProperty(ns, 'default', { enumerable: true, value: value });/******/    if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));/******/    return ns;/******/  };/******//******/  // getDefaultExport function for compatibility with non-harmony modules/******/  __webpack_require__.n = function(module) {/******/    var getter = module && module.__esModule ?/******/      function getDefault() { return module['default']; } :/******/      function getModuleExports() { return module; };/******/    __webpack_require__.d(getter, 'a', getter);/******/    return getter;/******/  };/******//******/  // Object.prototype.hasOwnProperty.call/******/  __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };/******//******/  // __webpack_public_path__/******/  __webpack_require__.p = "./";/******//******/  // on error function for async loading/******/  __webpack_require__.oe = function(err) { console.error(err); throw err; };/******//******/  var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];/******/  var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);/******/  jsonpArray.push = webpackJsonpCallback;/******/  jsonpArray = jsonpArray.slice();/******/  for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);/******/  var parentJsonpFunction = oldJsonpFunction;/******//******//******/  // add entry module to deferred list/******/  deferredModules.push(["./src/index.js","vendors"]);/******/  // run deferred modules when ready/******/  return checkDeferredModules();/******/ })/************************************************************************//******/ ({/***/ "./src/index.js":/*!**********************!*\  !*** ./src/index.js ***!  \**********************//*! no exports provided *//***/ (function(module, __webpack_exports__, __webpack_require__) {"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/_react@16.7.0@react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ \"./node_modules/_react-dom@16.7.0@react-dom/index.js\");\n/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var react_router_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-router-dom */ \"./node_modules/_react-router-dom@4.3.1@react-router-dom/es/index.js\");\n/* harmony import */ var react_loadable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-loadable */ \"./node_modules/_react-loadable@5.5.0@react-loadable/lib/index.js\");\n/* harmony import */ var react_loadable__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react_loadable__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _index_less__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./index.less */ \"./src/index.less\");\n/* harmony import */ var _index_less__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_index_less__WEBPACK_IMPORTED_MODULE_4__);\n\n\n\n\n\n\nfunction LoadableAnotherComponent({\n  error\n}) {\n  if (error) {\n    return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", null, \"Error!\");\n  } else {\n    return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", null, \"Loading...\");\n  }\n}\n\nclass MyComponent extends react__WEBPACK_IMPORTED_MODULE_0___default.a.Component {\n  render() {\n    return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(LoadableAnotherComponent, null);\n  }\n\n}\n\nconst HomePage = () => react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", null, \"Home Page\");\n\nconst UsersPage = () => react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", null, \"Users Page\");\n\nfunction getUrl(url) {\n  return url;\n}\n\n;\nconst HomePage2 = react_loadable__WEBPACK_IMPORTED_MODULE_3___default()({\n  loader: () => __webpack_require__.e(/*! import() | home */ \"home\").then(__webpack_require__.bind(null, /*! ./component/homePage */ \"./src/component/homePage.js\")),\n  loading: MyComponent\n});\nconst UsersPage2 = react_loadable__WEBPACK_IMPORTED_MODULE_3___default()({\n  loader: () => __webpack_require__.e(/*! import() | user */ \"user\").then(__webpack_require__.bind(null, /*! ./component/userPage */ \"./src/component/userPage.js\")),\n  loading: MyComponent\n});\n\nfunction Layout() {\n  return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_2__[\"HashRouter\"], null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(\"div\", {\n    className: _index_less__WEBPACK_IMPORTED_MODULE_4___default.a.box\n  }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_2__[\"NavLink\"], {\n    exact: true,\n    to: \"/\"\n  }, \"\\u9996\\u9875\"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_2__[\"NavLink\"], {\n    to: {\n      pathname: '/users',\n      search: '?id=1',\n      state: {\n        name: '耿家寶'\n      }\n    }\n  }, \"\\u7528\\u6237\"), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_2__[\"Route\"], {\n    path: \"/\",\n    exact: true,\n    component: HomePage2\n  }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_router_dom__WEBPACK_IMPORTED_MODULE_2__[\"Route\"], {\n    path: \"/users\",\n    component: UsersPage2\n  })));\n}\n\nreact_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render(react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(Layout, null), document.getElementById('box'));\n\n//# sourceURL=webpack:///./src/index.js?");/***/ }),/***/ "./src/index.less":/*!************************!*\  !*** ./src/index.less ***!  \************************//*! no static exports found *//***/ (function(module, exports, __webpack_require__) {eval("// extracted by mini-css-extract-plugin\nmodule.exports = {\"box\":\"index-box-2pqZT\"};\n\n//# sourceURL=webpack:///./src/index.less?");/***/ })/******/ });複製程式碼


相關文章