webpack进阶-原理篇

·  阅读 404
webpack进阶-原理篇

打包原理

  1. 整理webpack.config,js等参数options合并到最终打包参数
  2. 调用webpack.complier,执行complier.run开始编译
  3. 生成compilation,compilation负责管理模块和依赖,确定入口并执行一系列hook
  4. 生成module
  5. 输出打包文件

相关hook介绍

Compiler:Compiler 模块是 webpack 的主要引擎,它通过 CLI 或者 Node API 传递的所有选项创建出一个 compilation 实例。 它扩展(extends)自 Tapable 类,用来注册和调用插件。 大多数面向用户的插件会首先在 Compiler 上注册

Tapable:这个小型库是 webpack 的一个核心工具,但也可用于其他地方, 以提供类似的插件接口。 在 webpack 中的许多对象都扩展自 Tapable 类。 它对外暴露了 taptapAsync 和 tapPromise 等方法, 插件可以使用这些方法向 webpack 中注入自定义构建的步骤,这些步骤将在构建过程中触发。

常用Compiler Hooks

run AsyncSeriesHook 在开始读取 records 之前调用。

runcompileemitdone
AsyncSeriesHookSyncHookAsyncSeriesHookAsyncSeriesHook
在开始读取 records 之前调用。beforeCompile 之后立即调用,但在一个新的 compilation 创建之前输出 asset 到 output 目录之前执行在 compilation 完成时执行

compilation 钩子

Compilation 模块会被 Compiler 用来创建新的 compilation 对象(或新的 build 对象)。 compilation 实例能够访问所有的模块和它们的依赖(大部分是循环依赖)。 它会对应用程序的依赖图中所有模块, 进行字面上的编译(literal compilation)。 在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)。

Compilation 类扩展(extend)自 Tapable,并提供了以下生命周期钩子。 可以按照 compiler 钩子的相同方式来调用 tap:

compilation.hooks.someHook.tap(/* ... */);
复制代码

manifest runtime

runtime:在浏览器运行过程中,webpack 用来连接模块化应用程序所需的所有代码。它包含:在模块交互时,连接模块所需的加载和解析逻辑。包括:已经加载到浏览器中的连接模块逻辑,以及尚未加载模块的延迟加载逻辑。
manifest:当 compiler 开始执行、解析和映射应用程序时,它会保留所有模块的详细要点。这个数据集合称为 "manifest",当完成打包并发送到浏览器时,runtime 会通过 manifest 来解析和加载模块。

热更新介绍

模块热替换(HMR - hot module replacement)功能会在应用程序运行过程中,替换、添加或删除 模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:

  • 保留在完全重新加载页面期间丢失的应用程序状态。
  • 只更新变更内容,以节省宝贵的开发时间。
  • 在源代码中 CSS/JS 产生修改时,会立刻在浏览器中进行更新,这几乎相当于在浏览器 devtools 直接更改样式。

热更新原理

webpack-dev-server先通过express起一个服务让浏览器能够访问本地静态资源,再起一个websocket能够与浏览器双向通信,每次编译结束,webpack监听到文件变化,再通过HotModuleReplacementPlugin获取到每次更新的hash值以及模块,通知浏览器更新。

Loader

module.exports = function(source){//去除console.log
    console.log("source",this.data)
    return source.replace(/console\.log\(.*\);/g, '');
}
resolveLoader: {//重命名
    alias: {
      loader1: path.resolve(__dirname, "./loader/loader1.js"),
    },
 },
复制代码

同步:return;异步:const callback = this.async

Plugin

// 一个 JavaScript 类
class MyExampleWebpackPlugin {
  // 在插件函数的 prototype 上定义一个 `apply` 方法,以 compiler 为参数。
  apply(compiler) {
    // 指定一个挂载到 webpack 自身的事件钩子。
    compiler.hooks.emit.tapAsync(
      'MyExampleWebpackPlugin',
      (compilation, callback) => {
        console.log('这是一个示例插件!');
        console.log(
          '这里表示了资源的单次构建的 `compilation` 对象:',
          compilation
        );

        // 用 webpack 提供的插件 API 处理构建过程
        compilation.addModule(/* ... */);

        callback();
      }
    );
  }
}
复制代码

异步模块加载的实现原理

webpack_require.e方法创建了一个异步的script,并返回一个promises数组,resolve后执行 webpack_require(moduId),加载入口代码,从而 import() 逻辑加载完毕

Tree Shaking

比较导入和导出的模块

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改