Skip to content

webpack源码学习之cjs运行时分析

Published: at 01:05 PM

准备工作(接上篇文章的示例也可以): 1. 在index.js文件中引入任一js文件

import sum from "./sum";

const result = sum(1, 2);
console.log(result);

2. sum文件

const sum = (a, b) => {
  return a + b;
};

export default sum;

3. build.js文件

const path = require("path");
const webpack = require("webpack");

function wrapBuild() {
  return webpack({
    entry: "./index.js",
    mode: "none",
    output: {
      path: path.resolve(__dirname, "build"),
      filename: "[name].js",
    },
    infrastructureLogging: {
      debug: true,
      level: "log",
    },
  });
}

wrapBuild().run((err, stat) => {
  const startTime = stat.startTime;
  const endTime = stat.endTime;
  console.log("构建时间: ", endTime - startTime);
});

4. 命令行执行node ./build.js 生成打包产物main.js。(截图未完整, 共87行) 在这里插入图片描述 5. 什么是运行时代码? 通过webpack打包得到的文件(如/build/main.js的骨架代码), 其中包含了一些webpack如何将多个模块集合在一起的代码, 可粗暴理解为webpack runtime 打包过后的代码。可通过node build/main.js可直接调试。 6. 示例打包js资源后的运行时代码分析:(含注解)

/******/ (() => {
  // webpackBootstrap
  /******/ "use strict";
  /******/ var __webpack_modules__ = [
    ,
    /* 0 */ // ---模块0, 入口模块 可以理解为index.js模块
    /* 1 */ // ---模块1,打包过后的sum.js
    /***/ (
      __unused_webpack_module,
      __webpack_exports__,
      __webpack_require__
    ) => {
      __webpack_require__.r(__webpack_exports__);
      /* harmony export */ __webpack_require__.d(__webpack_exports__, {
        /* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
        /* harmony export */
      });
      const sum = (a, b) => {
        return a + b;
      };

      /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = sum;

      /***/
    },
    /******/
  ];
  /************************************************************************/
  /******/ // 模块缓存
  /******/ var __webpack_module_cache__ = {};
  /******/
  /******/ // 模块加载器, 模拟实现common.js的require
  /******/ function __webpack_require__(moduleId) {
    /******/ // 根据moduleId从缓存中读取module
    /******/ var cachedModule = __webpack_module_cache__[moduleId];
    // 若缓存中存在该模块,则返回当前的module.exports
    /******/ if (cachedModule !== undefined) {
      /******/ return cachedModule.exports;
      /******/
    }
    /******/ // 缓存中不存在该模块,则去__webpack_modules__里取。
    // 创建一个新的模块,  写入cache对象, key为moduleId, value 为 exports对象
    /******/ var module = (__webpack_module_cache__[moduleId] = {
      /******/ // no module.id needed
      /******/ // no module.loaded needed
      /******/ exports: {},
      /******/
    });
    /******/
    /******/ // 调用包裹函数,计算模块信息,解析出相关模块内容(如:exports)
    /******/ __webpack_modules__[moduleId](
      module,
      module.exports,
      __webpack_require__
    );
    /******/
    /******/ // 返回当前解析过后的module.exports
    /******/ return module.exports;
    /******/
  }

  var __webpack_exports__ = {};
  // 加载入口函数
  (() => {
    __webpack_require__.r(__webpack_exports__);
    /* harmony import */ var _sum__WEBPACK_IMPORTED_MODULE_0__ =
      __webpack_require__(1);
    const result = (0, _sum__WEBPACK_IMPORTED_MODULE_0__["default"])(1, 2);
    console.log(result);
  })();

  /******/
})();

该运行时代码一共做了三件事:

7. 疑问?