安装使用generate-asset-webpack-plugin时报错TypeError:compiler.plugin is not a function,网上搜索了一下大概就是webpack5与这些插件不匹配。推荐的方法几乎都是换一个适配的插件版本,但我所需要的这个插件在npm上最近更新时间是7年前。等不着作者适配于是决定自己改。
找到报错的文件,搜索“compiler.plugin”定位到问题所在,修改写法(如下),打个补丁,提交一下✔️。
原先代码:
compiler.plugin('emit', function (compilation, cb) {})
修改后:
compiler.hooks.emit.tapAsync('GenerateAssetWebpackPlugin',(compilation,callback)=>{})
看到compiler的时候还不知道这是个啥东西,怎么就调了一个plugin方法。在当前文件没搜到后就开始了百度之旅(刚开始还以为plugin是创作者自定义的)。然后就了解到webpack的Compiler与Compilation 对象,个人理解Compiler粒度更大,类似于编译器实例,生命周期类似于APP的应用周期,整个生命周期只会执行一次(惨兮兮只有一条命)。
plugin是定义在webpack原型apply上的一个方法,用于调用webpack的钩子函数(类似于vue中mounted、created这种函数,会在特定的时间段进行调用),第一个参数为钩子函数名称,第二个参数为回调函数。关于钩子的种类及定义可查看文档compiler 钩子
但在webpack5中,plugin方法被取消了!所以报错is not a function。输出一下complier对象也会发现无这个属性【具体complier有什么属性可以看看依赖里的这个文件node_modules\webpack\lib\Compiler.js)
既然触发生命周期的方法变了,更新一下为最新版本的写法就好了。查看文档作出修改,至少问题就解决了~
所以这里输出的这些函数都是tapable中的,具体看文档 tapable,简单过一下定义后就看看那个插件generate-asset-webpack-plugin吧。webpack太长了关于其什么阶段调用了什么钩子就等把webpack基础概念和原理补完再看
这个代码挺少就看完了,查看官网自定义插件。自定义插件 | webpack 中文文档 | webpack 中文文档 | webpack 中文网
一个 JavaScript 命名函数或 JavaScript 类。
在插件函数的 prototype 上定义一个 apply 方法。
指定一个绑定到 webpack 自身的事件钩子。【这里就是指定的emit钩子
处理 webpack 内部实例的特定数据。【使用fs模块处理的
功能完成后调用 webpack 提供的回调。【callback结束异步操作
其他的还好,主要是不理解为什么不直接在插件函数原型上定义apply ,而要去调用一个自执行函数并使用 defineProperty给apply方法定义一些数据属性,是为了将apply()方法做响应式嘛?是的话这么做有啥好处呢?