cover 过去的一年里社区和业内对Vue的关注度不断增加,个人对Vue也可以说是一见钟情,最近团队产品的技术栈也都是以Vue为中心的,补一篇暑假就想写的关于部署的文章。

目标

  1. 前后端完全分离,最大程度上解耦
  2. nginx代理前端静态资源
  3. webhock 自动打包部署
  4. 生成更新日志

nginx配置

vue+webpack打包出来的文件做好了版本控制和依赖管理,nginx主要用来转发静态文件
后端只提供api,并单独部署在其他非对外端口,nginx负责将所有数据请求(有特殊url前缀)转发到后端服务 nginx 具体用法请自行google,这里只贴关键部分的配置

server{  
          listen 80;
          server_name  xxx.com;
          root /your/source/dist; # 静态资源目录
          index index.html; # 入口文件
          # 将数据请求转发到后端服务
          location /api {
                proxy_pass http://localhost:8087/api;
             }
         # 配合 html5 history 模式的前端路由,防止出现404
         location / {
            try_files /index.html =404;
          }
    }

webhock 自动部署并生成日志

webhock能明显提高工作效率,引用一张@shelter的图可以很形象的看出其优势。
图片

用nodeJs实现一个接受信号的小程序,具体代码只适合coding的webhock,github等同理

const http = require('http')  
const exec = require('exec')  
const fs = require('fs')

const PORT = 8004

const deployServer = http.createServer(function (request, response) {  
  let body = []
  request.on('error', function (err) {
    response.writeHead(500)
    response.end('server error\n' + err)
  }).on('data', function (chunk) {
    body.push(chunk)
  }).on('end', function () {
    body = Buffer.concat(body).toString()
    let deployMsg = false
    try {
      let json = JSON.parse(body)
      console.log(json)
      for (var i = 0; i < json.commits.length; i++) {
        if (json.commits[i].short_message.match('deploy')) {
          deployMsg = json.commits[i]
          break
        }
      }
      if (deployMsg) {
        let commands = [
          'git pull',
          `git reset --hard ${deployMsg.sha}`,
          'npm run build',
          'cp -r ./dist/* ./deploy'
        ].join(' && ')
        exec(commands, function (err, out, code) {
          if (err instanceof Error) {
            addLog(err, deployMsg)
            throw new Error(err)
          }
          addLog(null, deployMsg)
          process.stderr.write(err)
          process.stdout.write(out)
          response.writeHead(200)
          response.end('Deploy Done')
        })
      } else {
        response.writeHead(200)
        response.end('no Deploy')
      }
    } catch (e) {
      response.writeHead(500)
      response.end('server error\n' + e)
    }
  })
})

其实代码很简单,这里要说一下的是commands里面最后一个cp命令,把打包出来的文件复制到另一个目录如果重名就覆盖,deploy目录才是上线文件的目录。webpack打包时即使是一个chunk文件的更新都会把上次的文件全部删掉,在打包完成前dist目录是空的,这段时间会返回404,而且当项目很大时打包时间比较长,刚好webapck打包出的文件都有MD5签名,把打完的文件复制到上线文件目录还是相当安全的,弊端就是deploy目录会留下旧的废弃文件,定期清理就好。

顺便贴一下生成log文件的代码

const addLog = function (err, data) {  
  let date = new Date()
  let fileName = date.getFullYear() + '-' + (date.getMonth() + 1)
  let time = date.getHours() + '-' + date.getMinutes() + '-' + date.getSeconds()
  let writeMsg = `[${time}]: ${data.committer.name} has deploy width message ${data.short_message}`
  if (err) {
    writeMsg += '------deploy fail'
  }
  writeMsg += '\n'
  try {
    fs.open(`./logs/${fileName}.log`, 'a', (err, fd) => {
      if (err) {
        fs.writeFile(`./logs/${fileName}.log`, writeMsg, (err) => {
          if (err) {
            throw new Error(err)
          }
        })
      }
      fs.write(fd, writeMsg, (err) => {
        if (err) {
          throw new Error(err)
        }
      })
      console.log('done')
      fs.closeSync(fd)
    })
  } catch (e) {
    ...
  }
}

效果如下

▶ cat ./logs/2016-11.log 
[11-1-57]: scc has deploy width message test deploy
[11-2-26]: guyskk has deploy width message delete some deploy
[11-5-34]: scc has deploy width message test deploy
[11-7-26]: scc has deploy width message test deploy
[11-7-55]: scc has deploy width message test deploy------deploy fail
[11-7-56]: scc has deploy width message test deploy------deploy fail

pm2部署

webhock.js需要一直在有公网ip的服务器上运行等待调用,这里用pm2即可轻松部署

npm install pm2 -g  
pm2 start webhock.js  

大功告成

扫描二维码,分享此文章

scc