前端项目 node 自动部署
前言
主要借助于 ssh2、scp2
- ssh2
SSH2客户端和服务器模块是用纯JavaScript为node.js编写的。 开发/测试是在OpenSSH(目前是8.7)上完成的。
- scp2
scp2在很大程度上受ssh2的支持,以SFTP的方式实现了SCP。
它是用纯javascript编写的,应该在每个操作系统上工作,包含Windows。需要 Nodejs (v0.8.7或更新版本)才能使其工作。
第一步:安装依赖
- 过高版本的可能存在冲突问题,建议使用以下版本
// package.json
"devDependencies": {
"chalk": "^4.1.2",
"cross-env": "^7.0.3",
"ora": "^5.1.0",
"scp2": "^0.5.0",
"ssh2": "^1.11.0"
}
第二步:配置 npm 命令
// package.json
"scripts": {
"deploy:dev": "cross-env NODE_ENV=dev node ./deploy",
}
第三步:配置文件
与根目录新建
deploy文件夹于
deploy文件夹内新建config.js文件- 如果是用私钥连接服务器,则需要配置私钥文件与私钥密码
// deploy/config.js
/*
* 定义不同环境服务器信息根据 process.env.NODE_ENV 导出当前环境服务器相关信息
*/
const SERVER_LIST = {
// 测试服务器
dev: {
name: "测试环境", // 环境名称
host: "xxx.xxx.xxx.xxx", // ip
port: "xx", // 端口
username: "xxxx", // 服务器登录账号名称
password: "xxxxxxx", // 登录服务器登录密码,用私钥的话就可以注释掉,启用下面的私钥配置
// privateKey: require("fs").readFileSync("xxxxx"), // 本地的服务器私钥文件地址,需要用绝对路径,例如: deploy/private/dev.private
// passphrase: "xxxxx", // 服务器私钥密码
pathPrefix: "xxxxx", // 服务器前端项目文件夹的上级地址,以 / 结尾,如: /demo/
pathName: "xxxxx", // 服务器前端项目文件夹的名称
path: function () {
return `${this.pathPrefix}${this.pathName}`;
}, // 服务器前端项目的文件夹全路径地址
},
};
module.exports = SERVER_LIST[process.env.NODE_ENV];
- 于
deploy文件夹内新建index.js文件
const scpClient = require("scp2");
const ora = require("ora");
const chalk = require("chalk");
const server = require("./config");
const serverConfig = {
host: server.host,
port: server.port,
username: server.username,
password: server.password, // 用私钥就注释 password,启用下面的
// privateKey: server.privateKey,
// passphrase: server.passphrase,
};
const Client = require("ssh2").Client;
const conn = new Client();
// 服务器前端项目地址的上级目录地址(绝对地址)
const path = server.path();
// 备份文件夹名称,取当前时间
const currentTime = `$(date +"%Y-%m-%d~%H:%M:%S")`;
// 备份文件夹全路径(绝对地址)
const backUpUrl = `${server.pathPrefix}_backUp/${currentTime}`;
// 先判断前端项目文件夹是否存在,存在就进行备份,而后删除前端项目文件夹
const shellCmd = `if [ -d "${path}" ];then\n
echo "存在文件夹,进行拷贝"
cd ${server.pathPrefix}\n
mkdir -p ${backUpUrl}\n
cp -r ${path}/. ${backUpUrl}/\n
rm -rf ${path}\n
else\n
echo "不存在文件夹:${path}"
fi`;
conn
.on("ready", function () {
console.log("====> 连接成功 <====");
conn.exec(shellCmd, function (err, stream) {
if (err) throw err;
stream
.on("close", function (code, signal) {
console.log("====> 执行成功,关闭连接 <====");
// 部署前端项目
deployFile();
// 关闭 ssh2 连接
conn.end();
})
.on("data", function (data) {
console.log("STDOUT: " + data);
})
.stderr.on("data", function (data) {
console.log("STDERR: " + data);
});
});
})
.on("error", function () {})
.connect(serverConfig);
function deployFile() {
const spinner = ora("正在发布到" + (server.name) + "服务器...");
spinner.start();
scpClient.scp(
"dist/", // 本地打包后文件(绝对路径)地址
{
...serverConfig,
path,
},
function (err) {
spinner.stop();
if (err) {
console.log(chalk.red("发布失败.\n"));
throw err;
} else {
console.log(
chalk.green(
"Success! 成功发布到" + (server.name) + "服务器! \n"
)
);
}
}
);
}
第四步:配置.gitignore
服务器相关信息太过敏感,不建议上传至仓库,建议配置 .gitignore
# .gitignore
/deploy
Powered by Waline v2.15.8