前端简单自动部署脚本

背景

前端项目分开发、测试、生产环境,开发及测试已接入 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(), 'YYYYMMDDHHmm');
// 当前时间格式化
console.log((isRollback ? '回滚' : '部署') + '时间:' + curTime);

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

const ssh = new NodeSSH();

// 远程服务器配置信息
const config = {
  host: 'x.x.x.x',
  username: 'root',
  pathUrl: '/www/wwwroot/com/test/',
  privateKeyPath: 'xxxx' //秘钥路径,
  password:'xxx' // 或者密码
}

// 本地文件上传至远程服务器
function uploadFile() {
  ssh
    .connect({
      host: config.host,
      username: config.username,
      privateKeyPath: config.privateKeyPath,
      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!')
        fs.unlink(`${__dirname}/dist${curTime}.zip`, err => {
          if (err) throw err
        }) // 上传成功移除本地文件
        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配置 在 package.json 中追加命令去调用上面的 node 脚本。

注意要在服务器路径下建立一个dist文件

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

执行命令执行相应操作:

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

参考资料

文章转至:薛定喵君

作者:Lu
链接:https://llxx.cc/auto-deploy/
来源:Lu's Blog

THE END

打赏
< <上一篇
下一篇>>
文章目录
关闭
目 录