2022-11-14 前端自动化打包&压缩&上传服务器的脚本

280 阅读3分钟

前端代码一般都是压缩代码打完包后直接发布到服务器上部署,而打包这一块儿有webpack等工具很好的进行辅助,但是压缩和上传可以通过nodeJS服务端代码进行优化,以下就是在实际项目中的实战

压缩成zip包

在压缩zip包之前可能在需要在不同环境下,需要配置不同的域名和地址

比如在本公司的项目中,需要配置如下全局变量:

image.png 一般的话,有测试环境和线上环境,有可能还有客户指定的环境等,这时候需要几套不同的配置文件

当然最通常的办法就是把不同的部分提取出来,用函数的方式通过参数去控制,这个参数则需要通过命令行去获取

有两种方式获取参数:

    1. 通过process.argv获取所有命令行代码,诸如node index.js prod这种就有三个参数,截取第二个process.argv.splice(2)来获取到prod这个参数
    2. 通过指定参数key来获取,诸如node index.js --env prod,这里需要用yargs这个npm包去获取key的键值value,如require("yargs").argv.env就是prod参数

参数获取到后,根据参数修改配置文件,这里可以通过一个函数把不同环境的配置文件部分的代码修改掉,本项目中我使用的是把配置地址的文件根据不同环境分别生成一个,然后放在env文件夹下,之后在不同环境下替换掉相应的文件就可以,如下代码:

// 替换dist/config.js文件和dist/motorview/config.js文件
const replaceConfig = () => {
    // dist/config.js
    const fromFile = path.resolve(__dirname, `../env/${env}.js`);
    const toFile = path.resolve(__dirname, `../${config.directory}/config.js`);
    fs.copyFileSync(fromFile, toFile);

    // dist/motorview/config.js
    const fromMotorFile = path.resolve(__dirname, `../motor/${env}.js`);
    const toMotorFile = path.resolve(__dirname, `../${config.directory}/motorview/config.js`);
    fs.copyFileSync(fromMotorFile, toMotorFile);
};

fs.copyFileSync方法是nodeJS里的fs文件模块中替换指定文件的方法

这里是有三个环境的配置文件,放在了如下的文件夹里:

image.png

另外,在压缩之前需要先删除掉之前的压缩包,这里写了公共代码:

const path = require("path");
const fs = require("fs");

/**
 *根据正则查找文件名,返回满足正则条件的文件路径集合
 * @param {object} {startPath, reg}
 * @return {array} 文件路径集合
 */
const findFilePathSync = ({startPath, reg}) => {
    const result = [];
    const files = fs.readdirSync(startPath);
    files.forEach((val, index) => {
        const fPath = path.join(startPath, val);
        const stats = fs.statSync(fPath);
        // 满足正则条件的文件
        if (stats.isFile() && reg.test(fPath)) {
            result.push(fPath);
        }
    });
    return result;
};

// 删除dist压缩包
const deleteDistFiles = ({rootPath, reg}) => {
    // 压缩包路径
    const filePaths = findFilePathSync({startPath: rootPath, reg});
    filePaths.forEach(delFileName => {
        fs.unlinkSync(delFileName, err => {
            if (err) throw err;
            console.log("File deleted!");
        });
        const res = reg.exec(delFileName);
        if (res !== null) {
            console.log(`删除${res[0]}成功!`);
        } else {
            console.log(`删除${delFileName}成功!`);
        }
    });
};

exports.deleteDistFiles = deleteDistFiles;
exports.findFilePathSync = findFilePathSync;

先删除在替换

image.png

压缩成zip包使用了archiver这个npm包,压缩代码如下:

let {name} = require("./package.json");
let fs = require("fs");
let archiver = require("archiver");
const moment = require("moment");
const {uploadDist} = require("./script/uploadBetaDist");
const {config} = require("./script/config");

let args = process.argv.splice(2);
let time = moment().format("YYYY-MM-DD-HHmmss");

let args0 = args.length ? args[0] : undefined;
if (args0 === "prod") {
    // 正式
    packageName = `/${name}-prod-${time}.zip`;
} else if (args0 === "beta") {
    // 测试
    packageName = `/${name}-saas-beta-${time}.zip`;
} else {
    // 246
    packageName = `/dist.zip`;
}

let output = fs.createWriteStream(__dirname + packageName);

let archive = archiver("zip", {
    zlib: {level: 9}
});

output.on("close", () => {
    console.log("压缩完成");
    // 246环境直接上传到线上
    if (args0 === "246") {
        console.log("上传开始");
        uploadDist({
            uploadUrl: config.uploadUrl,
            rootPath: config.rootPath,
            distZipReg: config.distZipReg
        });
    }
});

output.on("end", () => {
    console.log("文件处理完成");
});

archive.on("warning", err => {
    if (err.code === "ENOENT") {
        console.log(err);
    } else {
        throw err;
    }
});

archive.on("error", err => {
    throw err;
});

archive.pipe(output);

archive.directory("dist/", false);

archive.finalize();

上传压缩包到服务器

本来这个工作可以手动上传压缩包,当然也可以写个node脚本用命令行执行代码

作为程序员,定是能用代码不要手动,编写程序如下:

// 上传代码到测试环境
const uploadDist = async ({uploadUrl, rootPath, distZipReg}) => {
    const filePaths = findFilePathSync({
        startPath: rootPath,
        reg: distZipReg
    });
    if (filePaths.length === 0) {
        console.log("请先将dist文件压缩成.zip格式,再上传代码");
        return;
    }
    if (filePaths.length >= 2) {
        console.log("在根路径下存在两个以上压缩包,请只保留一个压缩包");
    }
    const distZipPath = filePaths[0];
    try {
        const options = {
            method: "POST",
            uri: uploadUrl,
            headers: {
                "User-Agent":
                    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36",
                "Content-Type": "multipart/form-data"
            },
            formData: {
                myfile: fs.createReadStream(distZipPath) // 这里是关键
            }
        };
        const res = await request(options);
        console.log("代码上传246环境成功!");
        console.log("res", res);
    } catch (error) {
        console.log("error", error);
    }
};

至此,压缩代码上传服务器用脚本使用命令行就可以处理了