指望:javascript
思路html
實現 (代碼比較潦草,須要整理)vue
deploy.jsjava
// /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項目強制與遠端同步!!!本地代碼沒提交不要輕易進行操做!!!\n\n此操做git項目強制與遠端同步!!!本地代碼沒提交不要輕易進行操做!!!\n\n此操做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("\n")[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添加部署命令node
{ "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" } }
總結linux