webpack插件 自动部署到服务器

Webpack 通过 Plugin 机制让其更加灵活,以适应各种应用场景。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。

1. 基础的plugin

一个最基础的 Plugin 的代码是这样

javascript 复制代码
class BasicPlugin{
  // 在构造函数中获取用户给该插件传入的配置
  constructor(options){
  }

  // Webpack 会调用 BasicPlugin 实例的 apply 方法给插件实例传入 compiler 对象
  apply(compiler){
    compiler.plugin('compilation',function(compilation) {
    })
  }
}

// 导出 Plugin
module.exports = BasicPlugin;

在使用这个 Plugin 时,相关配置代码如下:

ini 复制代码
const BasicPlugin = require('./BasicPlugin.js');
module.export = {
  plugins:[
    new BasicPlugin(options),
  ]
}

Webpack 启动后,在读取配置的过程中会先执行 new BasicPlugin(options) 初始化一个 BasicPlugin 获得其实例。 在初始化 compiler 对象后,再调用 basicPlugin.apply(compiler) 给插件实例传入 compiler 对象。 插件实例在获取到 compiler 对象后,就可以通过 compiler.plugin(事件名称, 回调函数) 监听到 Webpack 广播出来的事件。 并且可以通过 compiler 对象去操作 Webpack。

2. Compiler和Compilation

在webpack的插件开发时,最经常用到的就是Compiler和Compilation,他们是webpack和plugin之间的桥梁

  • Compiler包含了所有webpack的配置信息,包含options、loader、plugins等信息。这个对象在Webpack启动时被实例化,它是全局唯一的,可以简单地将它理解为Webpack的实例
  • Compilation对象包含了当前的模块资源、编译生成资源、变化的文件等。当Webpack以开发模式运行时,每当检测一个文件发生变化,便有一次新的Compilation被创建。Compilation对象也提供了很多事件回调供插件进行扩展。通过Compilation也能读取到Compiler对象

两者的区别可以理解为:Compiler代表了整个Webpack从启动到关闭的生命周期,Compilation只代表一次新的编译

3. 事件流

Webpack就像一条生产线,要经过一系列处理流程才能将源文件转化成输出结果。这个生产线上每个流程的职责都是单一的,多个流程之间存在依赖关系,只有在完成了当前处理后才能提交给下一个流程处理。

Webpack在运行过程中会广播事件,插件只需要监听它关心的事情,就能加入这条生产线了,这就是插件的运行原理。

我们可以通过Compiler和Compilation对象来广播和监听事件

csharp 复制代码
// 广播事件
// event-name为事件名称,注意不要和现有的事件重名
// params为附带的参数
compiler.apply('event-name',params)

// 监听名称为event-name的事件,当event-name事件发生时,函数就会被执行
// 同时函数中的params参数为广播事件附带的参数
compiler.plugin('event-name',function(params){})

同理,compilation.apply和compilation.plugin的使用方法和前面讲解一致

4. 开发一个插件

通过前面的知识,我们已经可以开发一个简单的插件了,比如当Webpack成功编译和输出文件后执行发布操作,将输出的文件上传到服务器,同时该插件还能区分Webpack构建是否成功。

要实现该插件,需要借助以下两个事件:

  • done:在成功构建并且输出文件后,Webpack即将退出时发生
  • failed:在构建出现异常时导致构建失败,Webpack即将退出时发生

以下是该插件的用法

javascript 复制代码
module.exports = {
    plugins: [
        //在初始化EndWebpackPlugin时传入两个参数,分别是成功时的回调函数和失败时的回调函数
        new EndWebpackPlugin(() => {
            //Webpack构建成功,并且文件在输出时会执行到这里,这里就可以做发布文件操作
        },(err) => {
            //Webpack构建失败,err是导致错误的原因
            console.error(err)
        })
    ]
}

以下是实现这个插件

javascript 复制代码
class EndWebpackPlugin {
    constructor(doneCallback,failCallback){
        // 保存在构造函数中传入的回调函数,即我们在webpack.config.js实例化EndWebpackPlugin时传进来的两个参数
        this.doneCallback = doneCallback
        this.failCallback = failCallback
    }

    apply(compiler){
        compiler.plugin('done',(stats) => {
            // 在done事件中回调doneCallback
            this.doneCallback(stats)
        }),
        compiler.plugin('failed',(err) => {
            // 在failed事件中回调failCallback
            this.failCallback(err)
        })
    }
}

// 导出插件
module.exports = EndWebpackPlugin

我们还差最后一步,就是实现doneCallback,即将我们打包后的文件上传到我们的服务器,我们可以利用axios,通过post请求将打包出来的文件发送到我们服务器

javascript 复制代码
//完整代码

//webpack.config.js
const axios = require('axios')
module.exports = {
    plugins: [
        //在初始化EndWebpackPlugin时传入两个参数,分别是成功时的回调函数和失败时的回调函数
        new EndWebpackPlugin((compilation,callback) => {
    
        var url = 'http://10.0.0.0:78/upload' //服务器的url

        var upload = async function(name,content){
            await axios.post(url,{name,content})
        }

        for(let filename in compilation.assets){
            let content = compilation.assets[filename]['source']()
            upload(filename,content)
            callback()
        }
    },(err) => {
            //Webpack构建失败,err是导致错误的原因
            console.error(err)
        })
    ]
}

//uploade.js

class EndWebpackPlugin {
    constructor(doneCallback,failCallback){
        // 保存在构造函数中传入的回调函数,即我们在webpack.config.js实例化EndWebpackPlugin时传进来的两个参数
        this.doneCallback = doneCallback
        this.failCallback = failCallback
    }

    apply(compiler){
        compiler.plugin('done',() => {
            // 在done事件中回调doneCallback
            this.doneCallback()
        }),
        compiler.plugin('failed',(err) => {
            // 在failed事件中回调failCallback
            this.failCallback(err)
        })
    }
}

// 导出插件
module.exports = EndWebpackPlugin
相关推荐
裴嘉靖2 分钟前
Vue 生成 PDF 完整教程
前端·vue.js·pdf
毕设小屋vx ylw2824264 分钟前
Java开发、Java Web应用、前端技术及Vue项目
java·前端·vue.js
冴羽1 小时前
今日苹果 App Store 前端源码泄露,赶紧 fork 一份看看
前端·javascript·typescript
蒜香拿铁1 小时前
Angular【router路由】
前端·javascript·angular.js
brzhang1 小时前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构
西洼工作室2 小时前
高效管理搜索历史:Vue持久化实践
前端·javascript·vue.js
广州华水科技2 小时前
北斗形变监测传感器在水库安全中的应用及技术优势分析
前端
开发者如是说2 小时前
Compose 开发桌面程序的一些问题
前端·架构
旺代2 小时前
Token 存储与安全防护
前端
洋不写bug3 小时前
html实现简历信息填写界面
前端·html