基于 vue-cli 2 实现,vue 项目支持一键部署

vue 项目实现一键部署,热部署

Github项目地址

  1. 部署到服务器系统 ubuntu 或 centos(如果是其他服务器可能需要另写脚本)
  2. 使用 nginx 做静态服务器

实现思路

使用 node-ssh 或 ssh2 连接、上传静态资源并解压。
步骤:

  1. 编译、打包项目
  2. 调用脚本将打好的zip包上传到服务器
  3. 调用脚本执行解压到项目部署目录

以 vue-deploy-template 为例子:

nginx 部署目录:/home/website/vue-deploy-template/www/
包的上传目录:/home/upload/
准备一个账号,需要对部署的目录有读写执行的权限的账号,例如root

在项目目录下新建 deploy 文件夹及 deploy.js

const fs = require('fs')
const path = require('path')
const pack = require('../package.json')
const XEUtils = require('xe-utils')
const chalk = require('chalk')
const ora = require('ora')
const NodeSSH = require('node-ssh')
const argvs = process.argv.slice(2)

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

function getParams (key) {
  let item = argvs.find(item => item.split('=')[0] === key)
  return item ? item.split('=') : []
}

function getCommandParams (key, name) {
  if (getParams(key)[1]) {
    return {
      [name]: getParams(key)[1]
    }
  }
  return null
}

/**
 * 前端工程一键部署
 * 使用 WinSCP 工具
 *
 * 命令:npm run deploy u=root p=123456
 * 命令:npm run deploy
 */
let defOpts = {
  serverAddr: '127.0.0.1', // 服务器IP
  serverPort: '22', // ftp、sftp端口
  // userName: null, // 服务器用户名
  // password: null, // 服务器密码
  uploadPath: `/home/upload`, // 包发布历史存放目录
  libName: `dist.zip`, // 包名
  websitePath: `/home/website/${pack.name}/www`, // 项目部署站点路径
  websiteName: null // 自定义项目目录,默认使用项目名
}

function uploadDeploy (options) {
  let progressNum = 1
  let progressText = 'Auto deploy'
  let spinner = ora(`[${progressNum}%] ${progressText} ...`)
  let spInterval = setInterval(() => {
    if (progressNum < 99) {
      progressNum += XEUtils.random(1, 2)
    }
    spinner.text = `[${progressNum}%] ${progressText} ...\n`
  }, 1000)
  spinner.start()
  for (let key of ['userName', 'password', 'serverAddr', 'serverPort', 'uploadPath', 'websitePath']) {
    if (!options[key]) {
      throw new Error(`The ${key} cannot be empty. type=${options[key]}`)
    }
  }
  let startTime = Date.now()
  let websiteName = options.websiteName || pack.name
  let libName = options.libName
  let uploadPath = options.uploadPath.replace(/\/?$/, '')
  let websitePath = options.websitePath.replace(/\/?$/, '')
  let datetime = XEUtils.toDateString(startTime, 'yyyyMMddHHmmss')
  let ssh = new NodeSSH()
  progressText = 'Begin to connect'
  ssh.connect({
    host: options.serverAddr,
    port: options.serverPort,
    username: options.userName,
    password: options.password
  }).then(() => {
    progressText = 'Connection successful.'
    progressNum = Math.max(progressNum, 10)
    let uploadDir = uploadPath.substring(0, uploadPath.lastIndexOf('/'))
    let uploadNextPath = uploadPath.substring(uploadPath.lastIndexOf('/'), uploadPath.length)
    let websiteDir = websitePath.substring(0, websitePath.lastIndexOf('/'))
    let websiteNextPath = websitePath.substring(websitePath.lastIndexOf('/'), websitePath.length)
    return ssh.execCommand(`
    if [ ! -d ${uploadDir} ]; then
      mkdir ${uploadDir};
    fi
    if [ ! -d ${uploadDir}/${uploadNextPath} ]; then
      mkdir ${uploadDir}/${uploadNextPath};
    fi
    if [ ! -d ${uploadDir}/${uploadNextPath}/${websiteName} ]; then
      mkdir ${uploadDir}/${uploadNextPath}/${websiteName};
    fi
    if [ ! -d ${websiteDir} ]; then
      mkdir ${websiteDir};
    fi
    if [ ! -d ${websiteDir}/${websiteNextPath} ]; then
      mkdir ${websiteDir}/${websiteNextPath};
    fi
    `).then(() => {
      progressText = 'Lib uploaded'
      progressNum = Math.max(progressNum, 20)
      return ssh.putFile(resolve(libName), `${uploadDir}/${uploadNextPath}/${websiteName}/${libName}`)
    }).then(() => {
      progressText = 'Begin to deploy'
      progressNum = Math.max(progressNum, 90)
      return ssh.execCommand(`
      if [ -d ${websiteDir}/${websiteNextPath}/${websiteName} ]; then
        rm -rf ${websiteDir}/${websiteNextPath}/${websiteName};
      fi
      unzip ${uploadDir}/${uploadNextPath}/${websiteName}/${libName} -d ${websiteDir}/${websiteNextPath}/${websiteName}
      `)
    })
  })
    .then(() => {
      let color = `rgb(0,255,0)`
      let dateDiff = XEUtils.getDateDiff(startTime, Date.now())
      let deployTime = `${String(dateDiff.HH).padStart(2, 0)}:${String(dateDiff.mm).padStart(2, 0)}:${String(dateDiff.ss).padStart(2, 0)}`
      progressText = 'Deploy complete'
      progressNum = Math.max(progressNum, 100)
      ssh.dispose()
      setTimeout(() => {
        console.log(chalk`\n{bold.${color} Project Name:} ${websiteName}\n{bold.${color} Version:} ${pack.version}\n{bold.${color} Server:} ${options.type}://${options.serverAddr}:${options.serverPort}\n{bold.${color} Lib Path:} ${uploadPath}/${websiteName}/${libName}\n{bold.${color} Project Path:} ${websitePath}/${websiteName}\n{bold.${color} Datetime:} ${datetime}\n{bold.${color} Deploy Time:} ${deployTime}\n`)
        spinner.stop()
        clearInterval(spInterval)
      }, 1000)
    }).catch(e => {
      ssh.dispose()
      spinner.stop()
      clearInterval(spInterval)
      return Promise.reject(e)
    })
}

uploadDeploy(
  Object.assign(defOpts, {
    ...getCommandParams('u', 'userName'),
    ...getCommandParams('p', 'password'),
    ...getCommandParams('addr', 'serverAddr'),
    ...getCommandParams('port', 'serverPort')
  })
)

打开 package.json 文件增加 scripts 脚本命令

常用命令:
npm run dev 启动本地服务
npm run build 打包编译
npm run build:zip 用于生成 zip 包
npm run deploy 用于一键部署

"scripts": {
  // ...此处省略
  "build:zip": "node build/build.js zip",
  "deploy": "npm install && node build/build.js zip=dist && node deploy/deploy"
}

开始部署

执行:npm run deploy
编译中...

在这里插入图片描述
最后部署完成。打开页面访问即可。

查看项目

到此就完了,又愉快的玩耍了哈!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值