Nodejs一键发布脚本

背景

前端项目或者nodejs项目分开发、测试、生产环境,有的没有没有接入 jenkins。每次都需要进行本地打包, 手动压缩上传到服务器目录,ssh 登录服务器后备份旧文件, 手动删除文件再将包解压到指定目录,操作流程比较繁琐,需要提前了解服务器部署目录,不太友好。

目标

  • 根据packeage.json 的scripts 来配置测试和生产环境的脚本。

  • 根据运行脚本获取相关环境的配置

  • 在部署脚本里面处理环境配置,然后实现

    • SSH登陆服务器

    • 压缩目录

    • 上传文件到服务器

    • 备份并删除服务器上的原文件

    • 解压服务器上的文件

需要用到的包

npm install dotenv dotenv-cli node-ssh silly-datetime archiver

以下是对这几个包的简要说明:

  1. dotenv:dotenv是一个流行的Node.js库,用于从.env文件中加载环境变量,并使其在应用程序中可用。它可以帮助您在开发过程中轻松管理环境变量,而无需硬编码到代码中。
  2. dotenv-cli:dotenv-cli是dotenv的命令行工具,它允许您在命令行中运行脚本时加载.env文件中的环境变量。这对于在命令行中运行脚本或执行其他命令时,临时设置环境变量非常有用。
  3. node-ssh:node-ssh是一个用于在Node.js中执行SSH操作的库。它提供了一组API,使您可以连接到远程服务器,执行命令,上传和下载文件等。它对于在Node.js应用程序中与远程服务器进行交互非常有用。
  4. silly-datetime:silly-datetime是一个简单的日期和时间格式化工具。它提供了一些函数,可以帮助您格式化日期和时间,例如将日期格式化为指定的字符串,获取当前时间戳等。
  5. archiver:archiver是一个用于创建和提取归档文件(如zip、tar等)的库。它提供了一组API,使您可以创建压缩文件,添加文件或文件夹到压缩文件中,以及从压缩文件中提取文件。它对于在Node.js中处理归档文件非常有用。

代码

环境变量文件 .env.test

SERVER_IP=47.xx.xx.209
SERVER_USER_NAME=root
SERVER_PASSWORD=xxxxxxx
SERVER_PROJECT_PATH=/www/wwwroot/xxxx
DIST_PATH=dist

package.json

"scripts": {
   
    "build-deploy:test": "dotenv -e .env.test node deploy.js",
    "build-deploy:pro": "dotenv -e .env.production node deploy.js",
  }

部署代码 deploy.js

const fs = require('fs');
const path = require('path');
const archiver = require('archiver');
const {
   NodeSSH} = require('node-ssh');
const sd = require('silly-datetime');
// 加载配置文件
require('dotenv').config()
// 当前时间
const curTime = sd.format(new Date(), 'YYYYMMDDHH');
const distPath = path.resolve(__dirname, process.env.DIST_PATH);
const ssh = new NodeSSH();
// 远程服务器配置信息
let config = {
   
  host: process.env.SERVER_IP,
  username: process.env.SERVER_USER_NAME,
  password: process.env.SERVER_PASSWORD,
  pathUrl: process.env.SERVER_PROJECT_PATH,
}



// 本地文件上传至远程服务器
async function uploadFile() {
   
  try {
   
    await ssh.connect({
   
      host: config.host,
      username: config.username,
      password: config.password,
      port: 22,
    });
    console.log('SSH login success');
    await ssh.putFile(
      `${
     __dirname}/dist${
     curTime}.zip`,
      `${
     config.pathUrl}/dist${
     curTime}.zip`
    );
    console.log('The zip file is uploaded successfully');
    remoteFileUpdate();
  } catch (err) {
   
    console.log('The file upload failed:', err);
    process.exit(0);
  }
}

// 服务端远端文件解压,更新
async function remoteFileUpdate() {
   
  let cmd =`mv dist dist.bak${
     curTime} && unzip dist${
     curTime}.zip`;
  try {
   
    const result = await ssh.execCommand(cmd, {
   
      cwd: config.pathUrl,
    });
    console.log(`The update message is: ${
     result.stdout}`);
    if (!result.stderr) {
   
      console.log('Congratulations! Update success!');
      process.exit(0);
    } else {
   
      console.log('Something went wrong:', result);
      process.exit(0);
    }
  } catch (err) {
   
    console.log('SSH connection failed:', err);
    process.exit(0);
  }
}

// 本地文件压缩
function zipDirector() {
   
  try {
   
    const output = fs.createWriteStream(`${
     __dirname}/dist${
     curTime}.zip`);
    const archive = archiver('zip', {
   
      zlib: {
   level: 9},
    });
    output.on('close', (err) => {
   
      if (err) {
   
        console.log('Something went wrong with the zip process:', err);
        return;
      }
      uploadFile();//本地文件上传至远程服务器
      console.log(`${
     archive.pointer()} total bytes`);
      console.log('Archiver has been finalized and the output file descriptor has closed.');
    });
    output.on('end', () => {
   
      console.log('Data has been drained');
    });
    archive.pipe(output);
    //要压缩的文件夹路径,和输出路径
    // 设置本地 dist 文件路径
    console.log(distPath)
    // 将指定目录打包压缩到压缩包中,并且重命名为h5
    archive.directory(distPath, "dist");
    archive.finalize();
  } catch (e) {
   
    console.log(e)
  }
}

(function() {
   
  // 更新代码
  zipDirector();
})()

相关推荐

  1. Nodejs发布脚本

    2024-01-28 23:16:03       60 阅读
  2. k8s-node脚本扩容

    2024-01-28 23:16:03       53 阅读
  3. 安装docker脚本

    2024-01-28 23:16:03       30 阅读
  4. CentOS安装docker脚本

    2024-01-28 23:16:03       57 阅读
  5. 启动脚本,Karfka,RocketMQ

    2024-01-28 23:16:03       93 阅读
  6. Redis巡检脚本

    2024-01-28 23:16:03       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-28 23:16:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-28 23:16:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-28 23:16:03       82 阅读
  4. Python语言-面向对象

    2024-01-28 23:16:03       91 阅读

热门阅读

  1. torchvision.datasets的三个基础类

    2024-01-28 23:16:03       49 阅读
  2. C++ transform算法中toupper的使用

    2024-01-28 23:16:03       62 阅读
  3. ELK的详细解释

    2024-01-28 23:16:03       48 阅读
  4. 如何更干净地退出Go服务

    2024-01-28 23:16:03       58 阅读
  5. react hooks 的useMemo:

    2024-01-28 23:16:03       49 阅读
  6. strftime和strptime记忆

    2024-01-28 23:16:03       51 阅读
  7. C#中类型装换

    2024-01-28 23:16:03       47 阅读