4

前端项目nodejs自动部署脚本

 2 years ago
source link: http://xuedingmiao.com/blog/nodejs_auto_deploy.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一个脚本辅助部署前端项目

公司有些项目环境没有接入 jenkins 所以部署起来比较麻烦,所以写个脚本节约部署时间。

# 背景

前端项目分开发、测试、生产环境,开发及测试已接入 jenkins 自动部署,生产环境依然还是手动。每次都需要进行本地打包, 手动压缩上传到服务器目录,ssh 登录服务器后备份旧文件, 手动删除文件再将包解压到指定目录,操作流程比较繁琐,需要提前了解服务器部署目录,不太友好,所以就写了个脚本简化部署操作。

# 依赖安装

部署包含压缩文件、ssh 登录、文件上传等几个步骤,所以需要安装如下依赖:

  • archiver,压缩文件使用。
  • node-ssh,ssh 操作。
  • silly-datetime,时间处理。

# 关键代码

在项目根目录新建 deploy.js 脚本,作用是上传压缩包至服务器、备份旧文件,解压代码压缩包。

const fs = require('fs');
const path = require('path');
const archiver = require('archiver');
const { NodeSSH } = require('node-ssh');
const sd = require('silly-datetime');

let args = process.argv.splice(2),
  isRollback = args.includes('rollback');

// 当前时间
let curTime = sd.format(new Date(), 'YYYYMMDDHH');
// 当前时间格式化
console.log((isRollback ? '回滚' : '部署') + '时间:' + curTime);

// 设置本地 dist 文件路径
const distPath = path.resolve(__dirname, 'dist');

const ssh = new NodeSSH();

// 远程服务器配置信息
const config = require('./config');

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

// 远端文件更新
const remoteFileUpdate = () => {
  let cmd = isRollback
    ? `rm dist && mv dist.bak${curTime} dist`
    : `mv dist dist.bak${curTime} && unzip dist${curTime}.zip`;
  ssh
    .execCommand(cmd, {
      cwd: config.pathUrl,
    })
    .then((result) => {
      console.log(`The update message is: ${result.stdout}`);
      if (!result.stderr) {
        console.log('Gratefule! update success!');
        process.exit(0);
      } else {
        console.log('Something wrong:', result);
        process.exit(0);
      }
    });
};

// 本地文件压缩
const zipDirector = () => {
  const output = fs.createWriteStream(`${__dirname}/dist${curTime}.zip`);
  const archive = archiver('zip', {
    zlib: { level: 9 },
  }).on('error', (err) => {
    throw err;
  });
  output.on('close', (err) => {
    if (err) {
      console.log('something error width 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);
  archive.directory(distPath, '/dist');
  archive.finalize();
};

// 回滚代码
if (isRollback) {
  remoteFileUpdate();
} else {
  // 更新代码
  zipDirector();
}

服务器上的备份,解压等操作是通过执行 shell 命令做的,你也可以自己预先写好相关脚本去执行。

# 使用方法

在根目录新建一个 config.js 用于存放服务器 IP、用户名、密码、部署目录等信息,然后就可以在 package.json 中追加命令去调用上面的 node 脚本。

"scripts": {
    "deploy": "node deploy.js",
    "rollback": "node deploy.js rollback"
}

执行命令执行相应操作:

  • npm run deploy,部署 + 备份。
  • npm run rollback,回滚代码。

# 参考资料


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK