如何设计一个webpack插件?
安装webpack
首先我们创建一个文件夹webpack-plugin,执行:
1 | npm init |
如果你使用的是webpack 4+版本那么你还应该安装webpack-cli
1 | npm install --save-dev webpack-cli |
安装webpcak-dev-server
这个插件类似一个web服务器,不过它多了许多配置,我们通过配置它可以为我们时时编译刷新网页,为我们的开发带来方便,提高开发效率
1 | npm install --save-dev webpack-dev-server |
创建webpack.config.js
该文件是webpack 在打包以及启动服务时候所依赖的配置文件,我们也可以更改它的名称,这取决于以运行命令时候所依赖的package.json 文件中”script’字段配置,如图:
结构目录
编写一个插件
插件向第三方开发者提供了 webpack 引擎中完整的能力。使用阶段式的构建回调,开发者可以引入它们自己的行为到 webpack 构建流程中。创建插件比创建 loader 更加高级,因为你将需要理解一些 webpack 底层的内部特性来做相应的钩子,所以做好阅读一些源码的准备!
创建插件
webpack 插件由以下组成:
- 一个构造函数
- 在插件函数的prototype(原型属性)上添加一个apply方法
- 将插件函数实例挂载在webpack自身勾子函数上
- 处理 webpack 内部实例的特定数据
- 功能完成后调用 webpack 提供的回调
1 | // 创建一个插件类 |
Compiler 和 Compilation
在插件开发中最重要的两个参数就是 compiler 和 compilation 对象。理解它们的角色是扩展 webpack 引擎重要的第一步。
compiler 对象代表了完整的 webpack 环境配置。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置,包括 options,loader 和 plugin。当在 webpack 环境中应用一个插件时,插件将收到此 compiler 对象的引用。可以使用它来访问 webpack 的主环境。
compilation 对象代表了一次资源版本构建。当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。compilation 对象也提供了很多关键时机的回调,以供插件做自定义处理时选择使用。
详解Compiler
编译器钩子
Compiler模块是主引擎,它使用通过CLI或Node API传递的所有选项创建编译实例。它扩展了 Tapable类以注册和调用插件。大多数面向用户的插件首先在Compiler内。该模块是公开的webpack.Compiler,可以直接使用。
监听
Compiler监视文件系统和重新编译的文件改变。在观察模式中compiler会调用一些额外的事件如:watchRun,watchClose和invalid。这些事件通常应用于开发,webpack-dev-server就是一个典型的应用,我们在编写代码时候不用从新编译,webpack-dev-server会帮助我们时时编译。
勾子函数
- entryOption
- 同步勾子函数
- 在处理了webpack选项的entry配置后调用。
- 回调参数:context,entry
1
2
3compiler.hooks.entryOption.tap('MyPlugin', (context, entry) => {
/* ... */
});
- afterPlugins
- 同步函数
- 在设置初始内部插件集后调用。
- 回调参数: compiler
简单介绍两个如果大家有兴趣可以访问这里去学习。
详解Compiler
Compiler介绍
该Compilation模块用于Compiler创建新的编译(或构建)。compilation实例有权访问所有的模块和它们的依赖)。它是应用程序依赖关系图中所有模块的文字汇编。在编译阶段,模块被加载,密封,优化,分块,散列和恢复。
调用勾子函数
Compilation和compiler 一样具有针对不同生命周期的很多勾子函数,使用方法也差不多
1 | compilation.hooks.someHook.tap(/* ... */); |
在这里针对compilation的勾子函数我们就不一一介绍啦,如果您有兴趣可以点击这里进行学习
安装插件
1 | // webpack.config.js |
命令行执行:
1 | webpack-dev-server |
你可以看到命令行在执行完编译后将会打印:1
我是hello插件
总结
对于编写一个webpack插件,我们主要了解Compiler 和 Compilation他们的各种勾子函数,我们需要在什么时候做什么事,就清晰多了。谢谢。