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
相关推荐
多多米10051 小时前
初学Vue(2)
前端·javascript·vue.js
柏箱1 小时前
PHP基本语法总结
开发语言·前端·html·php
新缸中之脑1 小时前
Llama 3.2 安卓手机安装教程
前端·人工智能·算法
hmz8561 小时前
最新网课搜题答案查询小程序源码/题库多接口微信小程序源码+自带流量主
前端·微信小程序·小程序
看到请催我学习1 小时前
内存缓存和硬盘缓存
开发语言·前端·javascript·vue.js·缓存·ecmascript
blaizeer2 小时前
深入理解 CSS 浮动(Float):详尽指南
前端·css
编程老船长2 小时前
网页设计基础 第一讲:软件分类介绍、工具选择与课程概览
前端
编程老船长2 小时前
网页设计基础 第二讲:安装与配置 VSCode 开发工具,创建第一个 HTML 页面
前端
速盾cdn2 小时前
速盾:网页游戏部署高防服务器有什么优势?
服务器·前端·web安全
小白求学12 小时前
CSS浮动
前端·css·css3