重学webpack-工作原理概括以及bundle文件分析

74 阅读3分钟

webpack工作原理概括(面试)

webpack里的基本概念(非配置)

深入浅出webpack

  • Entry: Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。type: {[key:string]:string|Array<string>} | string
  • Module: 模块, 在webpack中 一切皆模块,一个模块对应一个文件,webpack会从配置的Entry中开始递归找出所有依赖模块
  • Chunk: 代码块,一个Chunk由多个模块组成,用于代码分割
  • Loader: 模块转换器,用于把模块原内容按照需求规则转换成新内容
  • Plugin: 扩展插件.在webpack构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在热定时机做对应的事.

webpack构建流程概括

流程步骤流程解释
初始化参数从配置文件(webpack.config.js)和shell或npm script语句中读取合并参数,得出最终的参数
开始编译使用上一步得到的参数初始化Compiler对象,加载所有配置的插件,执行对象的run方法进行编译
确定入口根据配置中的entry找出所有的入口文件
编译模块从入口文件出发,调用所有配置的loader对模块进行翻译,再找出该模块依赖的模块,再递归本步骤,直到所有入口依赖的文件都经过编译
完成模块编译编译完成,得到每个模块被翻译后的最终内容以及他们之间的依赖关系
输出资源根据入口和模块之间的依赖关系,组装成一个个包含多个模块的Chunk,再把每个Chunk转换成一个单独的文件加入到输出列表
输出完成根据配置的输出路径和文件名,吧文件内容写入到文件系统

webpack流程可分为三大阶段

  1. 初始化阶段: 启动构建,读取并且合并配置参数,加载Plugin,实例化Compiler.
  2. 编译阶段: 从Entry出发,针对每个Module串行调用对应的loader去翻译文件内容,再找到该Module依赖的Module,递归进行编译
  3. 输出阶段: 对编译后的Module组合成Chunk,把Chunk转换成文件,输出到文件系统

watch的情况:

开启watch监听模式, 文件发生变化会重新进行 编译 输出.

webpack输入文件(webpack4)

(function (modules) {
  // 缓存模块
  var installedModules = {};
  // 创建 requie函数,类似于node中的require
  function __webpack_require__(moduleId) {
    // 执行前检查要导入的模块是否在缓存中,存在则直接从缓存中导出模块
    if (installedModules[moduleId]) {
      return installedModules[moduleId].exports;
    }
    // 缓存中不存在,创建模块并且添加到缓存中
    var module = installedModules[moduleId] = {
      i: moduleId, // 模块路径 ./src/a.js
      l: false, // 模块是否执行
      exports: {} // 模块
    };
    // 从 modules 中获取 index 为 moduleId 的模块对应的函数
    // 再调用这个函数,同时把函数需要的参数传入
    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    // 修改标志位,标记已执行
    module.l = true;
    // 返回这个模块的导出值
    return module.exports;
  }
  // Webpack 配置中的 publicPath,用于加载被分割出去的异步代码
  __webpack_require__.p = "";

  // 从入口加载 
  return __webpack_require__(__webpack_require__.s = "./src/index.js");

})
  ({
    "./src/a.js":
      (function (module, exports, __webpack_require__) {
        eval("const b = __webpack_require__(/*! ./base/b */ \"./src/base/b.js\")\r\nmodule.exports = 'a' + b\n\n//# sourceURL=webpack:///./src/a.js?");
      }),
    "./src/base/b.js":
      (function (module, exports) {
        eval("module.exports = 'b'\n\n//# sourceURL=webpack:///./src/base/b.js?");
      }),
    "./src/index.js":
      (function (module, exports, __webpack_require__) {
        eval("const a = __webpack_require__(/*! ./a */ \"./src/a.js\")\r\nconsole.log(a)\n\n//# sourceURL=webpack:///./src/index.js?");
      })
  });