前端自动化部署

之前写项目在测试环境打包步骤为:打包,将dist内的文件拖拽到测试服务器上。这个过程比较麻烦,为了能简便一些,实现自动部署,我查了一下资料,较为简便的方法如下:

1.在package.json包中引入下面三个模块插件:ssh2、commander、archiver

也可以用命令行分别安装

npm install ssh2 --save 实现自动化上传

npm install commander --save 简化实现命令流程

npm install archiver --save 压缩工具-用来压缩文件


前端自动化部署_第1张图片
image

2.在config/prod.env.js进行如下配置:

包括服务器名称,账号,密码,项目名称(上传的文件夹名称),路径(上传路径)


"use strict";

const REMOTE_SERVER = '0.0.0.0'

const DEFAULT_HOST = {host: REMOTE_SERVER, user: 'xxx', password: 'xxx', key: '', name: 'xxx', path: '/home/tbc/smart_car/webapps'}

module.exports = {

    NODE_ENV: '"production"',

    REMOTE_HOST: REMOTE_SERVER,

    DEFAULT_HOST: DEFAULT_HOST,

};

3.修改buiild/build.js文件

在文件中引入一个commander,并给其配置参数,在最后对program.publish进行了判断,若存在则引入publish/publish-zip文件。到这一步为止,如果输入了npm run publish,这会完成相应的打包工作,并且引入了publish/publish-zip文件

前端自动化部署_第2张图片
image
前端自动化部署_第3张图片
image
'use strict'
require('./check-versions')()
const program = require('commander')
//解析当前执行的命令行
var minimist = require('minimist')
let env = minimist(process.argv).env
console.log(env);
if (env === 'test') {
  process.env.NODE_ENV = 'testing'
  process.env.npm_config_report = true
}else {
  process.env.NODE_ENV = 'production'
}
console.log("process.env.NODE_ENV="+process.env.NODE_ENV);

const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')

const spinner = ora('building for production...')
spinner.start()
program
  .version('0.0.1')
  .option('-p, --publish', 'Publish Remote')
  .parse(process.argv)
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
  if (err) throw err
  webpack(webpackConfig, (err, stats) => {
    spinner.stop()
    if (err) throw err
    process.stdout.write(stats.toString({
      colors: true,
      modules: false,
      children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
      chunks: false,
      chunkModules: false
    }) + '\n\n')

    if (stats.hasErrors()) {
      console.log(chalk.red('  Build failed with errors.\n'))
      process.exit(1)
    }

    console.log(chalk.cyan('  Build complete.\n'))
    console.log(chalk.yellow(
      '  Tip: built files are meant to be served over an HTTP server.\n' +
      '  Opening index.html over file:// won\'t work.\n'
    ))
   
    if (program.publish) {
      console.log('-----');
      require('../publish/publish-zip')()
    }
    
  })
})

4.在根目录下创建publish文件夹,在publish内创建publish-zip文件,提供压缩方法.压缩完成后引入publish.js文件

文件内容如下:


const fs = require('fs')

const archiver = require('archiver')

const env = require('../config/prod.env')

// const chalk = require('chalk')

module.exports = function () {

//   console.log(chalk.cyan('  Zip files.\n'))

//   console.time('key')

  var output = fs.createWriteStream(`publish/${env.DEFAULT_HOST.name}.zip`)

  var archive = archiver('zip')

  output.on('close', function () {

    // console.log(chalk.cyan('  Zip files.\n'))

    // console.timeEnd('key')

    console.log('compress completed...ready upload')

    require('./publish.js')()

  })

  output.on('end', function () {

  })

  archive.on('error', function (err) {

    throw err

  })

  archive.pipe(output)

  archive.glob('./dist' + '/**')

  archive.finalize()

}

5.在publish文件夹内创建publish.js用来上传文件、删除文件

代码如下:


const env = require('../config/prod.env')

const chalk = require('chalk')

var Client = require('ssh2').Client

var conn = new Client()

var fs = require('fs')

const user = {

  host: env.DEFAULT_HOST.host,

  port: 20022,

  username: env.DEFAULT_HOST.user,

  password: env.DEFAULT_HOST.password

}

/**

 * 1.进入目录

 * 2.删除旧的备份项目

 * 3.将原项目名称加上bak标志为备份文件

 * 4.解压缩上传的zip文件并将名称改为项目名称

 * 5.删除zip文件

 * 6.退出

 * @type {string[]}

 */

const uploadShellList = [

  `cd ${env.DEFAULT_HOST.path}\n`,

  `rm -rf ${env.DEFAULT_HOST.name}.bak\n`,

  `mv ${env.DEFAULT_HOST.name} ${env.DEFAULT_HOST.name}.bak\n`,

  `unzip ${env.DEFAULT_HOST.name}.zip\n`,

  `mv dist ${env.DEFAULT_HOST.name}\n`,

  `rm -rf ${env.DEFAULT_HOST.name}.zip\n`,

  `exit\n`

]

const params = {file: `./publish/${env.DEFAULT_HOST.name}.zip`, target: `${env.DEFAULT_HOST.path}/${env.DEFAULT_HOST.name}.zip`}

/**

 * 上传文件

 * @param conn

 * @param params

 * @constructor

 */

function UploadFile (conn, params) {

  const file = params.file

  const target = params.target

  if (!conn) {

    return

  }

  conn.sftp(function (err, sftp) {

    if (err) {

      throw err

    }

    sftp.fastPut(file, target, {}, function (err, result) {

      if (err) {

        console.log(chalk.red(err.message))

        throw err

      }

      Shell(conn)

    })

  })

}

function Ready () {

  conn.on('ready', function () {

    console.log('Client :: ready')

    UploadFile(conn, params)

  }).connect(user)

}

/**

 * 上传完成后服务器需要执行的内容

 * 删除本地压缩文件

 * @param conn

 * @constructor

 */

function Shell (conn) {

  conn.shell(function (err, stream) {

    if (err) throw err

    stream.on('close', function () {

      console.log('Stream :: close')

      conn.end()

      fs.unlinkSync(`./publish/${env.DEFAULT_HOST.name}.zip`)

    }).on('data', function (data) {

      console.log('STDOUT: ' + data)

    }).stderr.on('data', function (data) {

      console.log('STDERR: ' + data)

    })

    stream.end(uploadShellList.join(''))

  })

}

module.exports = function () {

  try {

    Ready()

  } catch (err) {

    console.log(err)

  }

}

6.更改打包部署指令

在原来打包指令的基础上加了一个 -p

通过监听这个参数,来判断是只进行打包还是打包上传

前端自动化部署_第4张图片
image

至此,自动部署已配置完成,通过 npm run publish即可自动打包部署啦!

你可能感兴趣的:(前端自动化部署)