以前的前端改改上传就能用,现在的前端十个有九个要编译才能用,😂。每次编译都得重新上传,总结起来就俩字:麻烦,于是乎,研究了一下自动部署。
自动部署
服务端编译:在服务端编译,编译完了再自动部署到指定目录
本地编译:在本地编译,编译完了自动上传到服务端的指定目录
1.服务端编译
本着安全、方便的角度,一开始想的是在服务端实现一个能自动拉取Git仓库并编译部署的任务队列,然后通过Git的Webhook去触发更新自动部署。
实现后发现存在一个很致命的缺陷:项目较为复杂并且服务器配置一般般时,Vite编译的过程会占用大量内存导致编译无法完成(进程会因为内存占用超出限制被自动Kill)
服务器配置够用的话,可以试试:github.com/friend-nice...
2.本地编译
这种实现起来就比较简单,编译完成后自动运行Node脚本,同步项目文件到服务器,使用方法如下:
- 在项目目录内创建vite目录
- 复制下面的代码到vite目录下的deploy.mjs
- 修改package.json,新增如下命令:
json
{
"scripts": {
"deploy": "vite build && node vite/deploy.mjs"
}
}
本着安全的前提,连接SSH所用的账号最好限制其文件目录权限(仅能访问部署的目录和文件)
脚本代码如下,按照注释进行配置修改:
javascript
import {NodeSSH} from "node-ssh";
import * as fs from "fs";
import path from 'path';
/* 修改为服务器的SSH配置 */
const sshConfig = {
host: "12.0.0.1",
port: 22,
username: "root",
privateKeyPath: "api.pem",
};
/* 部署后需要复制的文件/目录 */
/* source:本地文件或目录路径 */
/* target:上传到服务器(目录后面必须加/,不加/会导致上级目录被删除) */
const deploy = [
{
source: './dist/admin',
target: '/www/wwwroot/diy/admin/'
},
{
source: './dist/index.html',
target: '/www/wwwroot/diy/index.html'
}
]
/**
* 上传部署
* @return {Promise<void>}
*/
const main = async () => {
const ssh = new NodeSSH();
try {
await ssh.connect({
host: sshConfig.host,
port: sshConfig.port,
username: sshConfig.username,
privateKeyPath: sshConfig.privateKeyPath,
});
/* 复制文件到目标目录 */
for (const file of deploy) {
console.info(`准备复制: ${file.source} -> ${file.target}`);
/* 检查目标目录是否存在,如果存在则删除 */
if ((await ssh.execCommand(`if [ -d "${file.target}" ]; then echo "exists"; else echo "not_exists"; fi`)).stdout.trim() === 'exists') {
await ssh.execCommand(`rm -rf "${file.target}"`);
console.info(`删除目标目录: ${file.target}`);
}
/* 检查本地文件是否存在 */
if (!fs.existsSync(file.source)) {
console.error(`本地文件不存在: ${file.source}`);
continue;
}
/* 确保目标目录存在 */
const targetDir = path.dirname(file.target);
/* 创建 */
await ssh.execCommand(`mkdir -p "${targetDir}"`);
console.info(`正在上传: ${file.target}`);
/* 判断是文件还是目录 */
if (file.target.endsWith('/')) {
/* 如果是目录,使用 putDirectory 方法上传 */
await ssh.putDirectory(file.source, file.target, {
recursive: true, // 递归上传
concurrency: 10, // 并发数
validate: (filePath) => {
/* 排除 macOS 的 .DS_Store 文件 */
return filePath !== path.join(file.source, '.DS_Store');
}
})
} else {
/* 如果是文件,使用 putFile 方法上传 */
await ssh.putFile(file.source, file.target);
}
console.info(`上传成功: ${file.target}`);
}
} catch (e) {
console.error('部署失败:' + e.message);
} finally {
ssh.dispose(); // 断开连接
}
};
main();
运行 npm run deploy ,来完成自动编译上传部署