之前写项目在测试环境打包步骤为:打包,将dist内的文件拖拽到测试服务器上。这个过程比较麻烦,为了能简便一些,实现自动部署,我查了一下资料,较为简便的方法如下:
1.在package.json包中引入下面三个模块插件:ssh2、commander、archiver
也可以用命令行分别安装
npm install ssh2 --save 实现自动化上传
npm install commander --save 简化实现命令流程
npm install archiver --save 压缩工具-用来压缩文件
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文件
'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
通过监听这个参数,来判断是只进行打包还是打包上传
至此,自动部署已配置完成,通过 npm run publish即可自动打包部署啦!