webpack-upload-plugin自动上传前端包至服务器

662 阅读2分钟

平时前端打完包是怎么传给后台的呢,是不是先压缩dist目录,再通过微信,qq,钉钉等工具。厌倦了重复的工作,于是在公司内网搭建了一个FTP服务器,不同项目打完包以后,标明版本号,以后上传至该FTP服务器,后端人员都从该服务器下载,通过版本号就可以拿到当下最新的版本。

每次打包前端需要手动通过FTP工具上传也是费时费力,于是就写一个打包后自动压缩及上传FTP的插件,这样就方便许多,也可以避免手动上传带来的错误。

目前使用的时vue-cli 3.0搭建的项目, vue 2.6版本,

用到的三方插件ftp, zip-webpack-plugin

package.json

{
    "devDependencies": {
        "ftp": "^0.3.10",
        "zip-webpack-plugin": "^4.0.1"
    }
}

安装

npm i ftp zip-webpack-plugin -D

自定义插件Upload-plugin.js,放在项目根目录

const FtpClient = require("ftp");
const fs = require("fs");
const client = new FtpClient();
class UploadPlugin {
    constructor(options) {
        this.options = Object.assign(
            {
                sourcePath: `./dist/dist.zip`, //上传压缩包的路径,会被传进来的参数覆盖
                targetPath: "/", //FTP服务器路径,会被传进来的参数覆盖
                config: {
                    host: "192.168.252.72", //服务器地址
                    port: 10021, //服务器端口号
                    user: "fuser", //账号
                    password: "123456", //密码
                    keepalive: 10000
                }
            },
            options || {}
        );
    }

    apply(compiler) {
        compiler.hooks.afterEmit.tapPromise("UploadPlugin", compilation => {
            //我们一定要等待打包完毕,并且压缩完毕后才执行上传操作
            return this.upload(this.options.sourcePath, this.options.targetPath); 
        });
    }
    //上传
    async upload(sourcePath, targetPath) {
        if (!fs.existsSync(sourcePath)) {
            return false;
        }
        await this.connect();
        return new Promise((resolve, reject) => {
            client.put(sourcePath, targetPath, err => {
                client.end();
                if (err) {
                    console.log(err);
                    reject(false);
                } else {
                    console.log(`upload file completed. filePath: ${targetPath}`);
                    resolve(true);
                }
            });
        });
    }
    //连接FTP服务器
    connect() {
        return new Promise((resolve, reject) => {
            client.on("ready", () => {
                console.log("ftp ready");
                resolve();
            });
            client.on("close", () => {
                console.log("ftp close");
            });
            client.on("end", () => {
                console.log("ftp end");
            });
            client.on("error", err => {
                console.log("ftp err", err);
                reject(err);
            });
            client.connect(this.options.config);
        });
    }
}

module.exports = UploadPlugin;

vue.config.js使用

const ZipPlugin = require("zip-webpack-plugin"); //webpack压缩插件,打包后自动压缩
const UploadPlugin = require("./Upload-plugin"); //自定义webpack上传插件,上传至公司ftp服务器,供后台人员下载
const dayjs = require("dayjs");
const pkgConf = require("./package.json"); //加载package.json文件,方便拿到项目名称及版本号
const buildName = `front_ve_${process.env.VUE_APP_PLATFORM}_dev_v${pkgConf.version}_${dayjs().format("YYYYMMDDHHmmss")}`; //拼接打包后的名称,将必要信息添加进去,VUE_APP_PLATFORM是不同平台自定义的环境变量

const isProduction = process.env.NODE_ENV === "production"; //判断是否时生产环境
module.exports = {
    ...,
    outputDir: `dist/${buildName}`, //打包后存放的路径
    plugins: isProduction
            ? [
                  new ZipPlugin({
                      filename: `${buildName}.zip` //压缩后的包名
                  }),
                  new UploadPlugin({
                      sourcePath: `./dist/${buildName}/${buildName}.zip`, //指定打包后的资源文件地址(outputDir)
                      targetPath: `/head_web/terminal/pc/${buildName}.zip` //上传服务器存放路径
                  })
              ]
            : []
}