node脚本一键部署前端项目
概述
部署项目到云服务器的方案有很多种,比如Jenkins
,Git 的CI/CD
自动化工作流部署。由于Jenkins是居于Java的集成环境,需要在服务器搭建相关环境,Git的CI/CD也需要依赖Git的工作流去实现项目的部署,对于简单的小型测试应用,大可不必那么麻烦。于是查询网上众多方法,从中选择了Node脚本去运行部署前端项目
,以下是学习记录。
优点:
- 在package.json直接运行就可以部署到指定服务器。
- 配置简单,运行快
缺点:
- 不够自动化,每次运行都手动去修改服务器的登录账号密码
- 安全性不强,由于代码暴露在仓库中,所以不能将服务器密码账号保存到Git
部署原理
- 脚本通过
SSH
与远程服务器进行连接 - 打包后的代码通过
SFTP
传递到指定服务器目录 - 脚本
预设
远程服务器的Linux命令
进行操作文件 - 通过预设的
Linux命令
将打包文件备份
和移动到部署目录
- 最后通过
Nginx服务器
代理指定部署目录即可
相关代码
一、构建项目并压缩
由于windows命令下是无法直接操作shell脚本的,这里需要借助node去运行,当然不通过shell脚本也可,命令行单行执行,相关代码如下:
node执行压缩的shell脚本命令:
deploy.js
const cp = require('child_process');
const { resolve } = require('path');
// 压缩脚本路径 一定要双引号
const script = `"${resolve(__dirname, './pack.sh')}"`;
// 执行脚本获取输出流
let pro = cp.exec(script, (error) => {
if (error) {
console.error('------------compress err------------', error);
}
});
pro.stdout.pipe(process.stdout);
pro.on('exit', () => {
console.log('------------connect start------------');
// 执行到这里压缩脚本已经执行完成了,可以接着上传
});
shell 脚本 构建打包文件并压缩到指定目录:
pack.sh
echo '------------start packaging------------'
npm run build
echo '------------build end------------'
rm ./client/deploy.tar.gz
echo '------------clear end------------'
tar -cvzf ./client/deploy.tar.gz ./dist
echo '------------end packaging------------'
二、上传项目到服务器
整体代码:
deploy.js
const cp = require('child_process');
const ssh2 = require('ssh2');
const { resolve } = require('path');
// 压缩脚本路径 一定要双引号
const script = `"${resolve(__dirname, './pack.sh')}"`;
// 执行脚本获取输出流
let pro = cp.exec(script, (error) => {
if (error) {
console.error('------------compress err------------', error);
}
});
pro.stdout.pipe(process.stdout);
pro.on('exit', () => {
console.log('------------connect start------------');
connect();
});
// ssh客户端实例
const conn = new ssh2.Client();
/**连接服务器配置 */
const clientConfig = {
host: 'xxx.xxx.xxx.xx',
port: 22,
username: 'root',
password: 'xxxx',
};
// 部署根目录
const deployRootDir = '/www/wwwroot/web/';
// 部署目录
const deployDir = 'deploy/admin';
// 部署文件压缩包
const deployFile = 'deploy.tar.gz';
// 建立ssh 连接并上传
const connect = () => {
conn
.on('ready', () => {
console.log('------------connect success------------');
upload();
})
.connect(clientConfig);
};
/**上传文件到服务器 */
const upload = () => {
// 本地要上传的路径
const locationPath = resolve(__dirname, './deploy.tar.gz');
// 目标路径
const remotePath = '/www/wwwroot/web/deploy.tar.gz';
// 上传配置
const option = {};
// 上传回调
const callBack = (err) => {
err && console.error('------------upload err------------\n', err);
shell();
};
conn.sftp((err, sftp) => {
sftp && console.log('------------sftp ready------------');
// 开始上传
sftp.fastPut(locationPath, remotePath, option, callBack);
});
};
const shell = () => {
/**
* 1.备份数据到bak目录下,并以时间戳命名
* 2.清空原解压文件夹所有文件
* 3.解压到指定文件夹
* 4.删除原压缩文件
*/
// 部署脚本
const shellScript = `
cd ${deployRootDir}
cp ${deployFile} bak/bak.$(date "+%Y.%m.%d_%H:%M").tar.gz
rm -rf ${deployDir}/*
tar -zxvf ${deployFile} -C ${deployDir}
rm -rf ${deployFile}
exit
`;
conn.shell((err, stream) => {
stream
.end(shellScript)
.on('data', (data) => {
console.log(data.toString());
})
.on('close', () => {
conn.end();
console.log('------------connect end------------');
});
});
};
运行部署脚本
package.json
{
"scripts": {
"deploy":"node ./client/deploy.js",
}
}
相关文件目录