# 前期准备
# 从使用的角度来看插件
好了,我已经准备好阅读的这篇文章然后写一个炒鸡牛x的插件了,赶紧的。
额,等等,在这之前我们不是得知道需要怎么去做吗?我们总是听到的插件插件的,它到底是个啥啊?
对象?函数?类?
小伙伴们不妨结合我们已经用过的一些插件来猜猜,比如HtmlWebpackPlugin,我们会这样使用它:
module.exports = {
plugins: [
new HtmlWebpackPlugin({
title: 'custom-plugin'
})
]
}
可以看到,这很明显的就是个构造函数,或者是一个类嘛。我们使用new就可以实例化一个插件的对象。并且,这个函数或者类是可以让我们传递参数进去的。
那你脑子里是不是已经脑补出一个轮廓了呢?
function CustomPlugin (options) {}
// or
class CustomPlugin {
constructor (options) {}
}
# 从构建的角度来看插件
知道了plugin大概的轮廓,让我们从构建的角度来看看它。插件不同于loader一个很大的区别就是,loader它是一个转换器,它只专注于转换这一个领域,例如babel-loader能将ES6+的代码转换为ES5或以下,以此来保证兼容性,那么它是运行在打包之前的。
而plugin呢?你会发现市场上有各种让人眼花缭乱的插件,它可能运行在打包之前,也可能运行在打包的过程中,或者打包完成之后。总之,它不局限于打包,资源的加载,还有其它的功能。所以它是在整个编译周期都起作用。
那么如果让我们站在一个编写插件者的角度上来看的话,是不是在编写的时候需要明确两件事情:
- 我要如何拿到完整的
webpack环境配置呢?因为我在编写插件的时候肯定是要与webpack的主环境结合起来的 - 我如何告诉
webpack我的插件是在什么时候发挥作用呢?在打包之前?还是之后?也就是我们经常听到的钩子。
所以这时候我们就得清楚这几个硬知识点:
-
compiler对象代表了完整的 webpack 环境配置。这个对象在启动 webpack 时被一次性建立,并配置好所有可操作的设置,包括 options,loader 和 plugin。当在 webpack 环境中应用一个插件时,插件将收到此 compiler 对象的引用。可以使用它来访问 webpack 的主环境。 -
compilation对象代表了一次资源版本构建。当运行 webpack 开发环境中间件时,每当检测到一个文件变化,就会创建一个新的 compilation,从而生成一组新的编译资源。一个 compilation 对象表现了当前的模块资源、编译生成资源、变化的文件、以及被跟踪依赖的状态信息。compilation 对象也提供了很多关键时机的回调,以供插件做自定义处理时选择使用。 -
钩子的本质其实就是事件
# 案例准备
老规矩,为了能更好的让我们掌握本章的内容,我们需要本地创建一个案例来进行讲解。
创建项目的这个过程我就快速的用指令来实现一下哈:
mkdir webpack-custom-plugin && cd webpack-custom-plugin
npm init -y
cnpm i webpack webpack-cli clean-webpack-plugin html-webpack-plugin --save-dev
touch webpack.config.js
mkdir src && cd src
touch index.js
(mkdir:创建一个文件夹;touch:创建一个文件)
OK👌,此时项目目录变成了:
webpack-custom-plugin
|- package.