webpack plugin 从入门到入门 之compiler与compilation
前言
接上一篇章《webpack plugin从入门都入门》,带大家从4个常用Class(SyncHook
、SyncBailHook
、AsyncParallelHook
、 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({}) ] } 复制代码
安装webpack
与webpack-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
模块类似,因为Compiler
和 Compilation
类都继承了 Tapable
类。也是使用tapAsync
与tapPromise
。这里不展开描述,详情可以见官方文档。
compiler 和 compilation 具体是什么
compiler 和 compilation 是 webpack 打包构建过程中的核心对象,记录着打包的关键信息,并提供打包流程中对应的钩子供开发者在plugin中使用。
compiler
Compiler
类的实例,webpack 从开始执行到结束,Compiler
只会实例化一次。compiler 对象记录了 webpack 运行环境的所有的信息,插件可以通过它获取到 webpack 的配置信息,如entry、output、module
等配置。
compilation
Compilation
类实例,提供了 webpack 大部分生命周期Hook API供自定义处理时做拓展使用。一个 compilation 对象记录了一次构建到生成资源过程中的信息,它储存了当前的模块资源、编译生成的资源、变化的文件、以及被跟踪依赖的状态信息。
简单来说,Compilation
的职责就是对所有 require 图(graph)中对象的字面上的编译,编译构建 module 和 chunk,并调用插件构建过程,同时把本次构建编译的内容全存到内存里。compilation 编译可以多次执行,如在watch模式下启动 webpack,每次监测到源文件发生变化,都会重新实例化一个compilation对象,从而生成一组新的编译资源对象。这个对象可以访问所有的模块和它们的依赖。
总结
这篇文章在读者对tapable有一定印象的前提下。重点解释compiler
与compilation
的概念与实践架构。
compiler
对象记录着构建过程中 webpack
环境与配置信息,整个 webpack
从开始到结束的生命周期。针对的是webpack。
compilation
对象记录编译模块的信息,只要项目文件有改动,compilation
就会被重新创建。针对的是随时可变的项目文件。
下一篇最终篇将会介绍 plugin 的其他 API,并用添加 plugin 开发的示例来深入阐述webpack plugin。
作者:Doerme
链接:https://juejin.cn/post/7068930184887402509