webpack---自定义插件(plugin)

136 阅读2分钟

plugin会在webpack初始化时,给相应的生命周期函数绑定监听事件,直至webpack执行到对应的那个生命周期函数,plugin绑定的事件就会触发。

自定义插件

  • 第一步认识plugin plugin本质上是一个对外导出的class,类中包含一个固定方法名apply.

apply函数的第一个参数就是compiler,我们编写的插件逻辑就是在apply函数下面进行编写:

  • 第二部编写plugin 程序中已经获取了compiler参数,那我们就可以在compiler的各个钩子函数中绑定监听事件。
  • 第三步 处理逻辑 compilation.assets 存放着即将输出到文件系统的内容,如果这时候我们操作compilation.assets数据,势必会影响最终打包的结果。

自定义插件基本写法

    /**
     * 1. webpack 加载 webpack.config.js 中所有的配置,此时会 new TestPlugin(),执行插件的 constructor.
     * 2. webpack创建compiler对象。
     * 3. 遍历所有 plugins 中插件, 调用插件的 apply方法。
     * 4. 执行剩下编译流程(触发各个hooks事件。)
     */

    class TestPlugin {
        constructor() {
            console.log('TestPlugin constructor')
        }
        apply(compiler) {
            console.log('TestPlugin apply')
        } 
    }
    module.exports = TestPlugin

自定义插件---静态文件自动上传到服务器中

依赖包:node-ssh:通过ssh连接远程服务器(安装npm i node-ssh -D)

const {NodeSSH} = require('node-ssh')
class AutoUploadWebpackPlugin{
  constructor(options){
   this.ssh = new NodeSSH()
   this.options = options
  }
  // 1.webpack读取配置时,new AutoUploadWebpackPlugin(),会执行插件constructor方法
  // 2.webpack创建compiler对象
  // 3.遍历所有插件,调用插件的apply方法
  apply(compiler){
     //compile hook是SyncHook,同步钩子,只能用tap注册
    compiler.hooks.afterEmit.tapAsync("AutoPlugin",async(compilation,callback)=>{
     // 1.获取输出文件夹路径
     const outputPath =compilation.outputOptions.path
     // 2.连接远程服务器 ssh
     await this.connectServer()
     // 3.删除原有的文件夹中内容
     const remotePath = this.options.remotePath
     this.ssh.execCommand(`rm -rf ${remotePath}/*`)
     // 4.将文件夹中资源上传到服务器中
     await this.uploadFiles(outputPath,remotePath)
     //5.关闭ssh连接
     this.ssh.dispose()
     //完成所有的操作后,调用callback()
     callback()
    })
  }
  
  async connectServer(){
   await this.ssh.connect({
    host:this.options.host,
    username:this.options.username,
    password:this.options.password,
   })
  }
  
  async uploadFiles(localPath,remotePath){
   const status = await this.ssh.putDirectory(localPath,remotePath,{
    recursive:true,
    concurrency:10
   })
   if(status){
    console.log("文件上传服务器成功")
   }
  }
}
module.exports = AutoUploadWebpackPlugin
module.exports.AutoUploadWebpackPlugin = AutoUploadWebpackPlugin

webpack的plugins中,使用该类:

const AutoUploadWebpackPlugin = require('./AutoUploadWebpackPlugin')
module.exports = {
  plugins:[
   new AutoUploadWebpackPlugin({
     host:'',
     username:'',
     password:,
     remotePath:""
   })
  ]
}