NodeSSh 实现前端自动部署:服务端编译和本地编译

原文:nicen.cn/8377.html

以前的前端改改上传就能用,现在的前端十个有九个要编译才能用,😂。每次编译都得重新上传,总结起来就俩字:麻烦,于是乎,研究了一下自动部署。

自动部署

服务端编译:在服务端编译,编译完了再自动部署到指定目录

本地编译:在本地编译,编译完了自动上传到服务端的指定目录

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 ,来完成自动编译上传部署

相关推荐
Face4 小时前
Node.js全栈基石(壹)
前端·node.js
mosen8685 小时前
易混淆的CommonJS和ESM(ES Module)及它们区别
javascript·node.js·express
袁袁袁袁满1 天前
基于nvm安装管理多个node.js版本切换使用(附上详细安装使用图文教程+nvm命令大全)
运维·node.js·nvm·nvm安装·多个node.js版本切换使用·nvm命令大全·node.js安装
Q_Q5110082851 天前
python的校园研招网系统
开发语言·spring boot·python·django·flask·node.js·php
棒棒的唐1 天前
nodejs安装后 使用npm 只能在cmd 里使用 ,但是不能在poowershell使用,只能用npm.cmd
前端·npm·node.js
G等你下课1 天前
基于MCP构建一个智能助手
前端·node.js·mcp
JSPanda1 天前
Webpack插件开发避坑指南:三招制服Dev Server兼容性
webpack·node.js
濮水大叔2 天前
这个Database Transaction功能多多,你用过吗?
typescript·node.js·nestjs
鹧鸪yy2 天前
认识Node.js及其与 Nginx 前端项目区别
前端·nginx·node.js