import { Client } from "ssh2";
import SftpClient from "ssh2-sftp-client";
import { fileURLToPath } from "url";
import { dirname } from "path";
const sftp = new SftpClient();
// SSH 連接配置
const sshConfig = {
host: "xxx",
port: 22,
username: "xx",
password: "xxxx",
};
// 獲取當(dāng)前模塊的 URL
const __filename = fileURLToPath(import.meta.url);
// 獲取當(dāng)前模塊的目錄路徑
const __dirname = dirname(__filename);
const localFolderPath = `${__dirname}/../dist`; // 本地 dist 文件夾路徑
const remoteFolderPath = "/home/xxx"; // 遠(yuǎn)程服務(wù)器目標(biāo)文件夾路徑
/* 下面的可以不用動(dòng) */
// 封裝 SSH 連接函數(shù)為 Promise
const connectSSH = (sshConfig) => {
return new Promise((resolve, reject) => {
const conn = new Client();
conn
.on("ready", () => {
resolve(conn);
})
.connect(sshConfig);
conn.on("error", (err) => {
reject(err);
});
});
};
// 封裝連接 SSH 并執(zhí)行命令的函數(shù)為 Promise
const executeSSHCommand = (conn, command) => {
return new Promise((resolve, reject) => {
conn.exec(command, (err, stream) => {
if (err) {
conn.end();
reject(err);
return;
}
let stdout = "";
let stderr = "";
stream.on("data", (data) => (stdout += data.toString()));
stream.stderr.on("data", (data) => (stderr += data.toString()));
stream.on("close", (code, signal) => {
// conn.end();
if (code === 0) {
resolve(stdout);
} else {
reject(stderr || `Command failed with code ${code}`);
}
});
});
});
};
// 封裝上傳文件夾函數(shù)為 Promise
const uploadFolder = async (localFolderPath, remoteFolderPath) => {
await sftp
.connect(sshConfig)
.then(() => {
console.log("正在上傳中...");
return sftp.uploadDir(localFolderPath, remoteFolderPath);
})
.then(() => {
console.log("File uploaded successfully");
sftp.end();
})
.catch((err) => {
console.error(err.message);
sftp.end();
});
};
// 主函數(shù)
const main = async () => {
try {
// 連接 SSH
const conn = await connectSSH(sshConfig);
console.log("SSH 連接已建立");
// 刪除遠(yuǎn)程文件夾
await executeSSHCommand(conn, `rm -rf ${remoteFolderPath}/*`);
// 上傳文件夾
await uploadFolder(localFolderPath, remoteFolderPath);
// 關(guān)閉 SSH 連接
conn.end();
} catch (err) {
console.error("發(fā)生錯(cuò)誤:", err);
conn.end();
}
};
// 執(zhí)行主函數(shù)
main();
Vue3項(xiàng)目本地打包自動(dòng)上傳服務(wù)器
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 原因是當(dāng)前頁(yè)面style標(biāo)簽里面沒(méi)有添加scope。起到css不被組件之間重疊的作用。
- 準(zhǔn)備相關(guān)軟件 jenkins:中文網(wǎng)[https://www.jenkins.io/zh/download/] ...
- > 最近有童鞋把cue-cli升級(jí)到了3.0版本,原理是一樣的,在項(xiàng)目中新建文件比如`upload.js`,在pa...
- vue項(xiàng)目打包后,將文件復(fù)制到服務(wù)器顯然是很麻煩,于是結(jié)合網(wǎng)上的資料,寫下這篇自動(dòng)化部署的記錄。 一、安裝 scp...
- 說(shuō)明:前后端分離的vue項(xiàng)目,為了解決跨域問(wèn)題,需要部署到j(luò)ava web項(xiàng)目的resources/static目...