聊聊如何开发一款webpack插件

2,025 阅读2分钟

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

介绍

相信我们写webpack的时候经常使用的两大操作就是使用插件和loader,他们两个有很多共性,比如说都可以处理不同类型的文件,但也有很多的不同,webpack插件与loader相比,插件没有向loader那般独立的运行环境,因为webpack插件只能在webpack中运行。但插件目的在于去解决loader无法实现的事,比如从打包优化和压缩,到重新定义环境变量,再到美化监测打包过程,其功能强大到可以用来处理各种各样的任务。

本期的任务就是带大家对webpack插件了解一下,并开发出一个简单的插件demo来,还等什么,我们马上出发~

开发

// my-plugin.js
class MyPlugin{     // 插件名称
    constructor(options){
        this.options = options;    
    }
    apply(compiler){  // apply方法
        console.log("This is My Plugin!");
    	compiler.hooks.done.tap("My Plugin", stats => {   // 监听hooks
            console.log("My author is "+this.options.name) // 处理逻辑
	})
    }
}
module.exports = MyPlugin;

基础结构还是非常简单的,constuctor在传递信息,apply中做一些使用,并且apply是必须要有的,它会传递一个compiler对象,上面的代码是监听插件的hooks在其执行结束后,去写入逻辑打印输出了些字符串,比如我们传递了一个名字看它会不会在控制台打印出来。

接下来,写完后我们就可以尝试在webpack.config.js中使用一下。

// webpack.config.js
const MyPlugin = require('./webpack-plugin/my-plugin.js');
const plugins=[
    // ...more plugin
    new MyPlugin({
        name:"Mask"
    })
]
module.exports = {
  // ...
  plugins
}

写完这些,我们就可以去构建一下看看效果了。

# NPM
npm run build
# YARN
yarn build

微信截图_20220125233329.png

这样就可以看我们先输出了This is My Plugin!,而后等待hooks完成的时候把后面的My author is Mask也输出了出来,这样我们的一个小插件案例就完成了。

注意

我们在开发插件的时候需要遵循的CommonJS规范,所以引入其他库的话不能使用es6的引入方式(即:import from),而是需要使用require。

如下代码改造:

var chalk = require('chalk');

class MyPlugin{
    constructor(options){
        this.options = options;    
    }
    apply(compiler){
        console.log(chalk.green("This is My Plugin!"));
    	compiler.hooks.done.tap("MyPlugin", stats => {
            console.log(chalk.italic("My author is ")+ chalk.yellow.bold.italic(this.options.name)+"\n")
	})
    }
}
module.exports = MyPlugin;

我们引入一个chalk库,他可以改变控制台输出文本的样式或者颜色,这里我们用了chalk3.0.0的版本,这个版本可以直接用require引入,接下来执行构建,发现没有问题,需要改变的文本样式出现了。

微信截图_20220125235415.png

结语

看完这个demo,是不是感觉写款插件也不是那么的难,因为能拿到compiler,我们可以在任何地方去监听webpack,然后去做自己想做的事,但是前提是要对webpack的周期有相对的了解才行,目前我们对这一块还是九牛一毛,后面有时间会跟大家分享下对于开发webpack的一些进阶操作和案例。