自动备份html文件,基于vue cli的前端自动部署,自动备份index.html,可版本退回

期望:

希望通过npm命令实现远程服务端部署

部署分测试环境、生产环境

打包部署前必须保证本地代码为最新代码,与git服务器同步

需要保留vue cli的版本管理,上传代码前备份index.html,方便版本退回

思路

定义测试环境与生产环境的配置对象,包括host、port、username、password、path(部署路径)、outputDir(打包文件夹)

拉取所在分支最新代码,保证本地代码与git服务器一致(git fetch --all && git reset --hard origin/branchName && git pull,操作给出提示,确保本地有用代码已经提交)

通过env环境打对应的包

通过ssh2,远程执行linux stat命令,获取index.html文件的最后修改时间,工具这个时间生成版本号

通过ssh2,执行linux的cp命令,拷贝服务器上index.html,重命名为index.201911081804.html(201911081804为index.html的最后修改时间)

用scp2插件上传打包好的文件到服务器目标目录

实现 (代码比较潦草,需要整理)

deploy.js

// /deploy.js

const scpClient = require("scp2");

const exec = require("child_process").exec;

const execSync = require("child_process").execSync;

const readline = require("readline");

/*

*定义多个服务器账号

*/

const SERVER_LIST = {

// 测试环境

test: {

name: "测试环境",

host: "", // ip

port: 22, // 端口

username: "root", // 登录服务器的账号

password: "@", // 登录服务器的账号

path: "/home/static/cnhpec", // 发布至静态服务器的项目路径

outputDir: "dist/" // 打包的目录 对应vue.config的outputDir配置

},

// 开发环境

prod: {

name: "生产环境",

host: "",

port: 22,

username: "root",

password: "@",

path: "/home/static/cnhpec",

outputDir: "dist/"

}

};

const argv = process.argv.slice(2);

const env = argv[0] ? (argv[0] === "prod" ? "prod" : "test") : "test";

const indexFile = SERVER_LIST[env].path + "/index.html";

const Client = require("ssh2").Client;

const conn = new Client();

conn

.on("ready", function() {

init();

})

.on("error", function(err) {

if (err) throw err;

})

.connect({

host: SERVER_LIST[env].host,

port: SERVER_LIST[env].port,

username: SERVER_LIST[env].username,

password: SERVER_LIST[env].password

});

async function init() {

await pull(); // 拉git最新代码

await build(); // 打包

await rename(); // 备份服务器代码,生成版本

await upload(); // 上传代码

}

function pull() {

return new Promise(function(resolve, reject) {

const rl = readline.createInterface({

input: process.stdin,

output: process.stdout

});

select();

function select() {

rl.question(

"此操作git项目强制与远端同步!!!本地代码没提交不要轻易进行操作!!!

此操作git项目强制与远端同步!!!本地代码没提交不要轻易进行操作!!!

此操作git项目强制与远端同步!!!本地代码没提交不要轻易进行操作!!!(y/n)",

function(answer) {

answer = answer.trim().toLowerCase();

if (answer === "y") {

const branch = execSync("git symbolic-ref --short HEAD");

exec(`git fetch --all && git reset --hard origin/${branch.toString()} && git pull`, function(err, stdout, stderr) {

if (err) {

console.error("项目强制与远端同步失败!!!");

reject();

throw err;

}

console.info(stdout.toString());

console.error(stderr);

console.log("项目强制与远端同步成功");

resolve();

});

rl.close();

} else if (answer === "n") {

reject();

rl.close();

process.exit(0);

} else {

select();

}

}

);

}

});

}

function build() {

return new Promise(function(resolve, reject) {

console.log(`开始打包${env === "prod" ? "生产" : "测试"}环境。。。。。。`);

exec("npm run " + env, function(err, stdout, stderr) {

if (err) {

console.error("打包失败!!!");

reject();

process.exit(1);

throw err;

}

console.info(stdout.toString());

console.error(stderr);

console.log("打包成功");

resolve();

});

});

}

function rename() {

return new Promise(function(resolve, reject) {

console.log("开始备份服务器版本。。。。。。");

conn.exec("stat " + indexFile, function(err, stream) {

if (err) {

console.error("服务器版本备份失败。。。。。。");

conn.end();

reject();

process.exit(1);

throw err;

}

let mtime;

stream

.on("close", function(code) {

if (code == 0) {

copy(mtime, resolve, reject);

} else {

resolve();

}

})

.on("data", function(data) {

console.info(data.toString());

mtime = data.toString().split("

")[7];

mtime = mtime.replace(/[u4e00-u9fa5]/g, "").replace(":", "");

mtime = formatDate(mtime);

})

.stderr.on("data", function(data) {

console.warn(data.toString());

});

});

});

}

function copy(mtime, resolve, reject) {

conn.exec("/bin/cp " + indexFile + " " + SERVER_LIST[env].path + "/index." + mtime + ".html", function(err, stream) {

if (err) {

console.error("服务器版本备份失败。。。。。。");

conn.end();

reject();

process.exit(1);

throw err;

}

stream

.on("close", function(code) {

if (code == 0) {

console.log("服务器版本备份成功");

resolve();

} else {

console.error("服务器版本备份失败。。。。。。");

conn.end();

reject();

process.exit(1);

}

})

.on("data", function(data) {

console.info(data.toString());

})

.stderr.on("data", function(data) {

console.error(data.toString());

});

});

}

function upload() {

return new Promise(function(resolve, reject) {

scpClient.scp(

SERVER_LIST[env].outputDir,

{

host: SERVER_LIST[env].host,

port: SERVER_LIST[env].port,

username: SERVER_LIST[env].username,

password: SERVER_LIST[env].password,

path: SERVER_LIST[env].path

},

function(err) {

conn.end();

if (err) {

reject();

process.exit(1);

throw err;

} else {

console.log("Success! 成功发布到" + (env === "prod" ? "生产" : "测试") + "服务器!");

resolve();

process.exit(0);

}

}

);

});

}

function formatDate(date) {

const isZero = m => (m < 10 ? "0" + m : m),

time = new Date(date),

y = time.getFullYear(),

m = time.getMonth() + 1,

d = time.getDate(),

h = time.getHours(),

mm = time.getMinutes(),

s = time.getSeconds();

return y + "" + isZero(m) + "" + isZero(d) + "" + isZero(h) + "" + isZero(mm) + "" + isZero(s);

}

package.json添加部署命令

{

"scripts": {

"serve": "vue-cli-service serve",

"build": "vue-cli-service build --mode build",

"test": "vue-cli-service build --mode test",

"lint": "vue-cli-service lint",

"i18n:report": "vue-cli-service i18n:report --src "./src/**/*.?(js|vue)" --locales "./src/locales/**/*.json"",

"deploy:test": "node ./deploy test",

"deploy:prod": "node ./deploy prod"

},

"devDependencies": {

"scp2": "^0.5.0"

}

}

总结

确保了代码最新来打包

保证版本可以退回

未考虑基于vue cli多页开发,html文件的版本备份

没有做成vue cli的插件

还是本地部署的,没有实现服务端部署,像jenkins一样(做出vue cli插件,在部署服务器上启动vue ui,访问http://ip:8000/tasks在里面点击deploy,可实现类型jenkins部署效果)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值