webpack plugin 从入门到入门 之compiler与compilation

「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。

前言

接上一篇章《webpack plugin从入门都入门》,带大家从4个常用Class(SyncHookSyncBailHookAsyncParallelHook、 AsyncSeriesHook)去了解tapable的常规用法。本文将会从webpack plugin的基本架构开展,介绍compiler与compilation。

写一个 webpack plugin 的基本架构

插件需要封装成class,当webpack安装插件时,会对class进行实例化,并调用实例下的apply方法。调用apply方法时候,会把compiler对象作为参数的形式传入,compiler是webpack底层编译对象的引用,开发者可以在apply方法实现中使用compiler

引用官方的代码片段如下:

class HelloCompilationPlugin {
  apply(compiler) {
    // 指定一个挂载到 compilation 的钩子,回调函数的参数为 compilation 。
    compiler.hooks.compilation.tap('HelloCompilationPlugin', (compilation) => {
      // 现在可以通过 compilation 对象绑定各种钩子
      console.log('现在可以通过 compilation 对象绑定各种钩子')
      compilation.hooks.optimize.tap('HelloCompilationPlugin', () => {
        console.log('资源已经优化完毕。');
      });
    });
  }
}

module.exports = HelloCompilationPlugin;
复制代码

tips: 代码片段中的tap方法,是不是让你回想起tapable的注册同步消费者。

HelloCompilationPlugin运行起来

|- plugins
    |- HelloCompilationPlugin.js
|- src
    |- index.js
|- webpack.config.js
复制代码

其中HelloCompilationPlugin.js内容如上文,index.js如下:

console.log('hello webpack plugin');
复制代码

webpack.config.js内容如下:

const HelloCompilationPlugin = require('./plugins/HelloCompilationPlugin')

module.exports = {
  mode: 'development',
  plugins: [
    new HelloCompilationPlugin({})
  ]
}
复制代码

安装webpackwebpack-cli依赖:

yarn add -D webpack webpack-cli
或
npm i -D webpack webpack-cli
复制代码

安装完成后执行:

./node_modules/webpack/bin/webpack.js
复制代码

在不指定配置文件路径的情况下,webpack cli 会默认使用执行目录根目录webpack.config.js作为执行配置。在不配置entry的情况下,默认用src/index.js作为编译打包入口,在不配置output的情况下默认使用dist目录作为打包产物的输出目录。

执行结果如下:

现在可以通过 compilation 对象绑定各种钩子
资源已经优化完毕。
asset main.js 1.21 KiB [compared for emit] (name: main)
./src/index.js 36 bytes [built] [code generated]
webpack 5.69.1 compiled successfully in 85 ms
复制代码

从控制台输出可得:

调用compiler.hooks.compilation.tap注册的同步钩子消费者被执行了。

调用compilation.hooks.optimize.tap注册的同步钩子消费者被执行了。

注册异步消费者

与上一篇章《webpack plugin从入门都入门》tapable模块类似,因为CompilerCompilation 类都继承了 Tapable 类。也是使用tapAsynctapPromise。这里不展开描述,详情可以见官方文档

compiler 和 compilation 具体是什么

compiler 和 compilation 是 webpack 打包构建过程中的核心对象,记录着打包的关键信息,并提供打包流程中对应的钩子供开发者在plugin中使用。

image.png

compiler

Compiler类的实例,webpack 从开始执行到结束,Compiler只会实例化一次。compiler 对象记录了 webpack 运行环境的所有的信息,插件可以通过它获取到 webpack 的配置信息,如entry、output、module等配置。

compilation

Compilation类实例,提供了 webpack 大部分生命周期Hook API供自定义处理时做拓展使用。一个 compilation 对象记录了一次构建到生成资源过程中的信息,它储存了当前的模块资源、编译生成的资源、变化的文件、以及被跟踪依赖的状态信息。

image.png

简单来说,Compilation的职责就是对所有 require 图(graph)中对象的字面上的编译,编译构建 module 和 chunk,并调用插件构建过程,同时把本次构建编译的内容全存到内存里。compilation 编译可以多次执行,如在watch模式下启动 webpack,每次监测到源文件发生变化,都会重新实例化一个compilation对象,从而生成一组新的编译资源对象。这个对象可以访问所有的模块和它们的依赖。

总结

这篇文章在读者对tapable有一定印象的前提下。重点解释compilercompilation的概念与实践架构。

compiler 对象记录着构建过程中 webpack 环境与配置信息,整个 webpack 从开始到结束的生命周期。针对的是webpack。

compilation 对象记录编译模块的信息,只要项目文件有改动,compilation 就会被重新创建。针对的是随时可变的项目文件。

下一篇最终篇将会介绍 plugin 的其他 API,并用添加 plugin 开发的示例来深入阐述webpack plugin。

Supongo que te gusta

Origin juejin.im/post/7068930184887402509
Recomendado
Clasificación