一:类型不同
loader 是一个函数
plugin 是一个class
二:侧重点不同,plugin更灵活,处理事情更多,但loader相对简单方便
loader 主要功能是告诉webpack如何加载一个一个资源,例如我们常用的vue-loader,就是告诉webpack,一个vue文件如何转化成对应的js文件;再如less-loader,告诉webpack,less的css语法,怎么转成浏览器能识别的css?
demo:
// 同步loader
module.exports = function(source) {
//处理输入,返回输出
return source;
};
//异步loader
module.exports = function (content,map,meta){
const callback = this.async();
setTimeout(() => {
callback(null, content); // 调用callback的时候才会执行
}, 10000;)
}
// 获取loader中的options
const {getOptions} = require('loader-utils');
module.exports = function (content, map, meta){
const options = getOptions(this); // 获取loader中的options
return options;
}
plugin :webpack打包过程中会埋一些事件钩子,例如emit,afteremit等等,plugin就是实现这些钩子,扩展webpack的能力,一般来说loader能做的,plugin都有对应的生命周期可以处理。还有些功能并不是要改到资源文件本身的,这种就只能用plugin,例如对代码做检测,拷贝文件等等
demo:
class FileWebpackPlugin{
constructor(options){
//接受参数
this.options = options
console.log('options', options); //sy-log
}
apply(compiler){
// 定义插件执行的时机(异步)
compiler.hooks.emit.tapAsync('FileWebpackPlugin', (compilation, callback)=>{
const packFilesLen = Object.keys(compilation.assets).length
let content = `本次构建结果统计:\n\r生成文件数量:${packFilesLen}个;\n\r`;
if(this.options.author){
content += `执行者:${this.options.author};\n\r`;
}
for (let filename in compilation.assets) {
content += `文件名称:${filename},文件大小:${compilation.assets[filename].size()};\n\r`;
}
compilation.assets['file.txt'] = {
source: function(){
return content
},
size: function(){
return 1024
}
}
callback()
})
//compiler.hooks.compile.tap("CopyrightWebpackPlugin", compilation => {
// console.log("开始了");
//});
}
}
module.exports = FileWebpackPlugin