依赖版本

"webpack": "^4.44.2","webpack-cli": "^3.3.12"

一个简略的文件通过webpack打包

// 导出console.log('index.js')module.exports = '导出内容'// 导入let log = require('./log.js')console.log('index.js内容')console.log(log)

打包后文件

 (function (modules) { // webpackBootstrap   // The module cache   var installedModules = {};   // 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     //  把index.js导出内容挂载到exports上     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;   }   // 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 = "";   // Load entry module and return exports   return __webpack_require__(__webpack_require__.s = "./src/index.js"); }) ({   "./src/index.js":     /*! no static exports found */     (function (module, exports) {       console.log('index.js内容')       module.exports = '入口文件导出内容'     }) });

打包文件剖析特点剖析

  1. 打包后的文件就是一个函数自调用,以后函数调用时传入一个对象。这个对象是一个键值对
  2. 这个键名就是以后被加载模块的文件名与某个目录的拼接()
  3. 这个键值就是一个函数,和 node.js 里的模块加载有一些相似,会将被加载模块中的内容包裹于一个函数中
  4. 这个函数在未来某个工夫点上会被调用,同时会接管到肯定的参数,利用这些参数就能够实现模块的加载操作
  5. 针对于上述的代码就相当于是将 {}(模块定义) 传递给了 modules


__webpack_require__办法是 webpack 当中自定义的,它的核心作用就是返回模块的 exports。
单文件模块打包产出文件,会失去一个自调用函数,模块定义会传给modules,在文件中会调用__webpack_require__办法,传入主入口文件id,导出内容会挂载到module.exports上,最初被返回给

  return __webpack_require__(__webpack_require__.s = "./src/index.js");

通过一个CommonJS单步调试,联合打包后代码能够晓得打包后文件一些办法的大略作用

 // 定义对象用于缓存已加载过的模块  var installedModules = {};//__webpack_require__办法是 webpack 自定义的一个加载办法,外围性能就是返回被加载模块中导出的内容(具体外部是如何实现的,后续再剖析)  function __webpack_require__(moduleId)// 将模块定义保留一份,通过 m 属性挂载到自定义的办法身上  __webpack_require__.m = modules; // o属性判断被传入的对象 obj 身上是否具备指定的属性*,如果有则返回 true   __webpack_require__.o = function (object, property) {    return Object.prototype.hasOwnProperty.call(object, property);  };  // define getter function for harmony exports  __webpack_require__.d = function (exports, name, getter) {    // 如果以后 exports 身上不具备 name 属性,则条件成立,增加成员属性name    if (!__webpack_require__.o(exports, name)) {      Object.defineProperty(exports, name, {        enumerable: true,        get: getter      });    }  // define __esModule on exports,给对象加一个标记,判断是否是esModule  __webpack_require__.r = function (exports) {    // 解决 esModule     if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {      // Object.prototype.toString.call(exports),增加键,值是Module      Object.defineProperty(exports, Symbol.toStringTag, {        value: 'Module'      });    }    // 如果条件不成立,咱们也间接在 exports 对象的身上增加一个 __esModule 属性,它的值就是true     Object.defineProperty(exports, '__esModule', {      value: true    });  };  // 调用 t 办法之后,咱们会拿到被加载模块中的内容 value,对于 value 来说咱们可能会间接返回,也可能会解决之后再返回  __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;  };