依赖版本
"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 = '入口文件导出内容' }) });
打包文件剖析特点剖析
- 打包后的文件就是一个函数自调用,以后函数调用时传入一个对象。这个对象是一个键值对
- 这个键名就是以后被加载模块的文件名与某个目录的拼接()
- 这个键值就是一个函数,和 node.js 里的模块加载有一些相似,会将被加载模块中的内容包裹于一个函数中
- 这个函数在未来某个工夫点上会被调用,同时会接管到肯定的参数,利用这些参数就能够实现模块的加载操作
- 针对于上述的代码就相当于是将 {}(模块定义) 传递给了 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; };