webpack打包分析
分析单文件打包:
- 打包index.js:
console.log(123);
- webpack打包后被放到一个立即执行函数中
- 会将入口文件的路径作为key,入口文件的内容作为value,放到一个对象中传递给立即执行函数
- 在自调用函数中实现了require方法,并且调用了自己实现的require方法
- 在调用自己实现的require时间入口文件路径作为key传递进去,然后通过这个路径取出对应的函数执行
(function (modules) { // webpackBootstrap // 1.初始化一个缓存,用来存放加载模块,缓存有则在缓存中取,没有才去读取文件 var installedModules = {}; // 2.自实现require方法,moduleId是自己调用自己传入的模块路径 function __webpack_require__(moduleId) { // 2.1判断缓存中有无当前需要的模块 if (installedModules[moduleId]) { return installedModules[moduleId].exports; } // 2.2创建一个模块,将其放入缓存 var module = installedModules[moduleId] = { i: moduleId, l: false, exports: {} }; /* 通过call执行模块函数,modules是传入的对象,key是模块路径,value是需要执行的函数,修改函数this为空对象,将module和module.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/js/index.js"); })({ "./src/js/index.js": (function (module, exports) { console.log(123); }) });
- 打包index.js:
分析多文件打包:
- a.js:
module.exports = "lnj";
- b.js:
module.exports = "33";
打包index.js:
const name = require('./a.js'); const age = require('./b/b.js'); console.log("it666"); console.log(name, age);
- 其他和单文件打包类似,唯一不同的是立即执行函数传入的参数不同
- 通过调用\__webpack_require\_\_方法,执行a.js和b.js中的代码,通过返回module.exports将值赋值给变量
({ "./src/js/a.js": (function (module, exports) { module.exports = "lnj"; }), "./src/js/b/b.js": (function (module, exports) { module.exports = "33"; }), "./src/js/index.js": (function (module, exports, __webpack_require__) { const name = __webpack_require__( /*! ./a.js */ "./src/js/a.js"); const age = __webpack_require__( /*! ./b/b.js */ "./src/js/b/b.js"); console.log("it666"); console.log(name, age); }) })
- a.js: