webpack的自定义插件学习
Plugin
webpack的插件可以加入自定义构建的行为,使webpack更加灵活的执行更广泛的任务
webpack在编译源码的过程中,会触发一系列的Tapable钩子事件,而插件就找到合适时机的钩子事件,向其挂载自己的任务,这样就会在webpack构建的时候随着钩子触发而执行
webpack生命周期两个核心对象compiler和compilation
Compiler
模块是 webpack 的主要引擎,它通过 CLI 或者 Node API 传递的所有选项创建出一个 compilation 实例。 它扩展(extends)自Tapable
类,用来注册和调用插件。 大多数面向用户的插件会首先在Compiler
上注册。
compiler的一些属性
compiler.options 可以访问本次启动 webpack 时候所有的配置文件,包括但不限于 loaders 、 entry 、 output 、 plugin 等等完整配置信息。
compiler.inputFileSystem 和 compiler.outputFileSystem 可以进行文件操作,相当于 Nodejs 中 fs。
compiler.hooks 可以注册 tapable 的不同种类 Hook,从而可以在 compiler 生命周期中植入不同的逻辑。
compilation 对象
compilation 对象代表一次资源的构建,compilation 实例能够访问所有的模块和它们的依赖。
一个 compilation 对象会对构建依赖图中所有模块,进行编译。 在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、 分块(chunk)、哈希(hash)和重新创建(restore)。
webpack执行顺序
自定义插件并挂载到Hook
class TestPlugin{
constructor(str){
console.log('str=============>',str)
}
apply(compiler){
//同步钩子
compiler.hooks.environment.tap("TestPlugin",() => {
console.log("enviroment");
})
compiler.hooks.emit.tap("TestPlugin",(compilation) => {
// console.log('compilation=============>',compilation)
})
//异步钩子
//emit是串行钩子,即钩子函数是一个个按顺序执行,例如以下需要花3s
compiler.hooks.emit.tapAsync("TestPlugin",(compilation,callback) => {
setTimeout(() => {
console.log("emit Async 111");
// console.log('compilation=============>',compilation)
callback()
}, 1000);
})
compiler.hooks.emit.tapPromise("TestPlugin",(compilation) => {
return new Promise((resolve,reject)=>{
setTimeout(() => {
console.log("emit Async 222");
resolve()
}, 2000);
})
})
//make是并行钩子,,以下需要花2s
compiler.hooks.make.tapAsync("TestPlugin",(compilation,callback) => {
setTimeout(() => {
console.log("make Async 111");
// console.log('compilation=============>',compilation)
callback()
}, 1000);
})
compiler.hooks.make.tapAsync("TestPlugin",(compilation) => {
return new Promise((resolve,reject)=>{
setTimeout(() => {
console.log("make Async 222");
resolve()
}, 2000);
})
})
//注册compilation的钩子
compiler.hooks.compilation.tap('TestPlugin', (compilation) => {
compilation.hooks.seal.tap('TestPlugin', () => {
console.log('compilation.hooks.seal hook called');
});
});
}
}
module.exports=TestPlugin
自定义clean-webpack-plugin
clean-webpack-plugin每次打包用于清除dist下目录的文件
class CleanWebpackPlugin {
apply(complier){
const outputPath = complier.options.output.path
const fs = complier.outputFileSystem
complier.hooks.emit.tap('CleanWebpackPlugin',(compliation) => {
this.removeFiles(fs,outputPath)
})
}
removeFiles(fs,outputPath){
const files = fs.readdirSync(outputPath)
files.forEach((file) => {
const pathfile = outputPath "\\" file
if(fs.statSync(pathfile).isFile()){
fs.unlinkSync(pathfile)
return
}else{
this.removeFiles(fs,pathfile)
}
//清空目录
fs.rmdirSync(pathfile)
})
}
//Api一行解决
// removeFiles(fs,outputPath){
// fs.rmdirSync(outputPath,{recursive:true})
// }
}
module.exports=CleanWebpackPlugin
自定义inline-chunk-plugin
将runtime等js文件改为内联的嵌入html的方式
runtime文件是用于解决缓存问题出现的
const HtmlWebpackPlugin = require('html-webpack-plugin');
class InlineChunkPlugin{
constructor({tests=[]}){
this.tests=tests
}
apply(compiler){
compiler.hooks.compilation.tap('InlineChunkPlugin', (compilation) => {
// console.log('The compiler is starting a new compilation...')
// Static Plugin interface |compilation |HOOK NAME | register listener
const hooks = HtmlWebpackPlugin.getHooks(compilation)
hooks.alterAssetTagGroups.tap("InlineChunkPlugin",(assets) => {
// console.log('assets.headTags=============>',assets.headTags)
/*
现在headTags的内容如下
{
tagName: 'script',
voidTag: false,
meta: { plugin: 'html-webpack-plugin' },
attributes: { defer: true, type: undefined, src: 'static/js/runtime~main.js' }
},
要修改为如下
{
tagName: 'script',
innerHTML: runtime文件内容
},
*/
assets.headTags= this.getInlineChunk(assets.headTags,compilation.assets)
//删除runtime文件
Object.keys(compilation.assets).forEach((filepath)=>{
if(this.tests.some((test)=> test.test(filepath) )){
delete compilation.assets[filepath]
}
})
})
}
)
}
getInlineChunk(headTags,assets){
return headTags.map ((tag) => {
if(tag.tagName!=='script') return tag
const filepath = tag.attributes.src;
if(!this.tests.some((test)=> test.test(filepath) ))return tag
return {
meta: { plugin: 'InlineChunkPlugin' },
tagName: 'script',
innerHTML: assets[filepath].source()
}
})
}
}
module.exports= InlineChunkPlugin
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhibefcf
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22