loader和plugin的区别
- loader:由于webpack本身能解析的只有js和json文件,那么,针对css、图片等格式的文件就需要第三方的模块进行打包,所以loader的作用是让webpack拥有了加载和解析非javascript的能力
- plugin: plugin可以扩展webpack的功能,让webpack具有更多的灵活性。在webpack运行的生命周期中会广播出许多事件,plugin可以监听这些事件,在合适的时机通过webpack提供的api改变输出结果
- loader运行在打包文件之前;plugin在整个编译周期都起作用
- loader的职责是单一的,只需要完成一种转换。
如何手写一个plugin
/**
* eg构建完成之后增加一个license的功能
* 必须是一个类
* 必须要有一个apply函数
* 必须要调用compiler APi来影响打包结果
*/
class LicenseWebpackPlugin{
constructor(params){
this.params = params
}
apply(compiler){
compiler.hooks.emit.tapAsync('',(compilation,cb)=>{
console.log(compilation.assets)
compilation.assets['LICENSE'] = {
source: function(){
return 'license xxx ...'
}
}
cb()
})
}
}
module.exports = LicenseWebpackPlugin
如何手写一个loader
同步loader
/**
* replace.js
* 这里不能用箭头函数,后期会改变this指向
* eg: 同步loader,实现将w换成大写W
*/
module.exports = function(content){
return content.replace(/w/g,'W')
}
异步loader
/**
* async-loader.js
* eg: 异步loader,同样实现文本修改
*/
const sleep = num=>new Promise((resolve)=>{
setTimeout(()=>{
resolve()
},num)
})
module.exports = function(content){
const callback = this.async()
;(async()=>{
await sleep()
content = content.replace(/W/,'www')
callback(null,content)
})()
}
引用
module.exports = {
entry: 'xxx',
module: {
rules: [
{
test: /.js$/,
use: [// loader解析顺序从后到前
path.resolve(__dirname,'./loaders/async-loader.js')
path.resolve(__dirname,'./loaders/replace.js')
]
}
]
}
}