目前项目一套代码会打包多个版本,进入测试阶段经常一个bug就要部署多套代码。为了节约时间(当然不可能是bug太多啦),写了一个自动批量打包部署的js脚本。
一、批量打包
- 通过node-cmd 批量执行打包命令 npm run build --client=${buildName} 不需要再去手动输入啦
const cmd = require("node-cmd");//通过js代码执行cmd命令的插件
const systemConfig = require("./client/config.json");//打包不同环境的配置
var deploy = require("./client/deploy-server");//自动部署逻辑
var args = require("node-args");//拿到命令行参数
// 获取所有系统名字集合
let systemName = Object.keys(systemConfig);//本次打包对应的环境参数
// 获取命令行参数 1234顺序对应系统名字
let buildArr = "";
try {
buildArr = args.s.toString().split("");//用数组表示批量部署时每次的环境参数
console.log(
`begin run build
预计打包时间${buildArr.length * 25}s`
);
} catch (e) {
console.log("缺少必填参数,例如 node runbuild.js --s=1234 -d=true");
//这里的1234分别代表四个环境的代码
return;
}
//用foreach 执行批量部署每次部署的任务
buildArr.forEach((item, i, arr) => {
let buildName = systemName[item - 1];
console.log(`
--------------------------begin build ${buildName}--------------------------------`);
let { err, data, stderr } = cmd.runSync(
`npm run build --client=${buildName}`
);
console.log(`
Sync Err ${err}
Sync stderr: ${stderr}
Sync Data ${data}
`);
if (!err) {
console.log(
`===============${buildName}打包完成=============================`
);
} else {
return;
}
//计数,等待全部打包完成,才开始部署
if (i === arr.length - 1 && args.d) {
console.log(`==============开始部署=============================、
${arr}
`);
deploy.conn(arr);
}
});
二、 自动压缩
- 用到了webpack的插件,每次webpack打包会自动执行这个插件
- 如果本地运行也是用的同一个配置文件,需要检查是否是生产的打包(如下),因为这个插件会拖慢本地项目响应的时间。
- 打包之后的文件操作是在这里配置的,基本逻辑是:将根目录下打包完成的dist文件压缩成zip、重命名并且存到根目录的zip目录中(等待部署),
const FileManagerPlugin = require("filemanager-webpack-plugin");
configureWebpack: {
plugins:
process.env.NODE_ENV === "production"
? [
new FileManagerPlugin({
events: {
onEnd: {
delete: [`./zip/${siteName}.zip`],
archive: [
{
source: path.join(__dirname, "./dist"),
destination: path.join(
__dirname,
`./zip/${siteName}.zip`
),
},
],
},
},
}),
]
: [],
},
三、自动部署
// 打包完成之后部署服务器
const Client = require("ssh2").Client;
var basename = require("path").basename;
//服务器的配置
const server = {
host: "172.18.10.114", // 服务器地址
port: "22", // 端口号
username: "root", // 用户名
password: "123456", // 密码
readyTimeout: 50000,
};
const connect = new Client();
const systemConfig = require("./config.json");
let systemName = Object.keys(systemConfig);
var fun = {
buildArr: null,
// 连接服务器
conn: function (buildArr = [1]) {
this.buildArr = buildArr;
connect
.on("ready", () => {
console.log("*******连接服务器*******");
this.upload();
})
.on("error", (err) => {
console.error(err);
console.log("*******连接出错*******");
})
.on("end", () => {
console.log("*******连接关闭*******");
})
.on("close", (err) => {
if (err) {
console.log("*******连接出错*******");
}
})
.connect(server);
},
upload: function () {
//用到了ssh2中的sftp 模块
connect.sftp((err, sftp) => {
if (err) {
console.log("sftp模块启动失败");
throw err;
}
console.log("sftp模块启动成功,开始批量上传文件");
let sucCount = 0;
let buildArrLen = this.buildArr.length;
this.buildArr.forEach((index) => {
let buildName = systemName[index - 1];
let remoteDir = `服务器前端部署路径-${buildName}/`;
let localDir = `./zip/${buildName}.zip`;
console.log(`*******${buildName}.zip 开始上传*******`);
sftp.fastPut(
localDir,
`${remoteDir}${basename(localDir)}`,
{},
(err, res) => {
if (err) {
console.log(err);
console.error("*******上传失败*******");
connect.end();
return;
}
sucCount++;
// 上传zip文件成功后
console.log(`*******${buildName}.zip上传成功*******`);
if (sucCount === buildArrLen) {
// 全部压缩包成功上传
console.log(`*******压缩包上传已完成,结束此次任务*******`);
process.exit();
}
}
);
});
});
},
};
module.exports = fun;
只需要手动输入 node runbuild.js --s=1234 -d=true 一条命令即可,这里的1234分别代表四个环境的代码 -d=true 代表需要自动部署
后面还可以优化:sftp模块支持传命令到服务器,不用去服务器操作文件了,真正实现了全自动部署哈哈。