aha-micro-cli
Version:
aha微前端运行脚手架
280 lines (246 loc) • 5.81 kB
JavaScript
/* 部署 */
const archiver = require('archiver')
const fs = require('fs')
const ora = require('ora')
const inquirer = require('inquirer')
const { NodeSSH } = require('node-ssh')
const {
resolve,
exit,
succeed,
error,
info
} = require('../utils/index')
const list = [
{
fn: selectEnv
},
{
fn: inputServerInfo
},
{
loading: 'ssh连接中...',
succeed: 'ssh连接成功!',
fn: connectSSH
},
{
fn: selectEnvEntry
},
{
text: '(1) 压缩打包项目',
loading: '压缩中...',
succeed: '压缩成功!',
fn: compressDir
},
{
text: '(2) 上传项目文件',
loading: '上传文件中...',
succeed: '上传文件成功',
fn: uploadLocalFile
},
{
text: '(3) 删除远程文件',
loading: '删除中...',
succeed: '删除成功',
fn: removeRemoteFile
},
{
text: '(4) 解压远程文件',
loading: '解压中...',
succeed: '解压成功',
fn: unzipRemoteFile
},
{
text: '(5) 删除本地压缩包',
loading: '删除中...',
succeed: '删除成功',
fn: removeLocalFile
},
{
text: '(6) 断开ssh连接',
loading: '断开ssh连接中...',
succeed: '断开ssh成功',
fn: disconnectSSH
},
]
const ssh = new NodeSSH()
let projects // 本次选中的项目
let env // 选中的环境
let configData // deploy配置数据
let server = { username: '', password: '' } // 服务器账号和密码
module.exports = async function() {
try {
/* 读取config文件 */
configData = require(resolve('micro-config')).deployConfig
for (const key in list) {
const item = list[ key ]
/* 步骤提示文字 */
item.text && console.log(item.text)
/* 加载动画 */
let spinner
if (item.loading) {
spinner = ora(item.loading)
spinner.start()
}
const log = await item.fn()
/* 关闭动画*/
spinner && spinner.stop()
/* 是否后置打印 */
if (Array.isArray(log)) {
log.forEach(item => info(item))
}
/* 成功提示 */
item.succeed && succeed(item.succeed)
}
succeed('部署完成!')
} catch (err) {
error(err)
process.exit(1)
}
}
/**
* 输入服务器账号和密码
*/
async function inputServerInfo() {
server = await inquirer.prompt([
{
type: 'input',
name: 'username',
message: '请输入服务器账号'
},
{
type: 'password',
name: 'password',
message: '请输入服务器密码'
}
])
}
/**
* 选择环境
*/
async function selectEnv() {
env = (await require('../utils/selectEnv')('请选择部署环境')).env
}
/**
* ssh连接
*/
async function connectSSH() {
const spinner = ora('ssh连接中')
try {
const { host, port } = configData[ env ]
await ssh.connect({ host, port, ...server })
} catch (e) {
error(e)
process.exit(1)
}
spinner.stop()
}
/**
* 选择发布环境和打包的项目
*/
async function selectEnvEntry() {
const res = await require('./build')('请选择需要部署的项目:', env)
projects = res.projects
}
/**
* 压缩包
*/
async function compressDir() {
try {
await Promise.all(projects.map(item => new Promise((resolve, reject) => {
const archive = archiver('zip', {
zlib: { level: 9 }
}).on('error', (e) => {
error(e)
})
const output = fs
.createWriteStream(`${ process.cwd() }/${ item.src }.zip`)
.on('close', (e) => {
if (e) {
error(`打包zip出错: ${ e }`)
reject(e)
exit(1)
} else {
resolve()
}
})
archive.pipe(output)
archive.directory(item.src, false)
archive.finalize()
})))
} catch (e) {
error(e)
process.exit(1)
}
}
/**
* 上传文件
*/
async function uploadLocalFile() {
const { webDir } = configData[ env ]
try {
await Promise.all(projects.map(item => {
const remotePath = `${ webDir }/${ item.entry }.zip`
const localPath = `${ process.cwd() }/${ item.distPath }.zip`
/* 压缩包上传到对应的项目文件夹下,与项目文件夹同名 */
return ssh.putFile(localPath, remotePath, null, {
concurrency: 1
})
}))
} catch (e) {
error(`上传文件失败: ${ e }`)
process.exit(1)
}
}
/**
* 删除原来远程的目录文件
*/
async function removeRemoteFile() {
try {
const { webDir } = configData[ env ]
await Promise.all(projects.map(item => {
const remotePath = `${ webDir }/${ item.entry }`
return ssh.execCommand(`rm -rf ${ remotePath }`)
}))
} catch (e) {
error(e)
process.exit(1)
}
}
/**
* 解压远程文件
*/
async function unzipRemoteFile() {
const log = []
try {
const { webDir } = configData[ env ]
await Promise.all(projects.map(item => {
const remotePath = `${ webDir }/${ item.entry }`
log.push(`${ item.name } 已部署至 ${ remotePath }`)
return ssh.execCommand(`unzip -o ${ remotePath }.zip -d ${ remotePath } && rm -rf ${ remotePath }.zip`)
}))
} catch (e) {
error(e)
process.exit(1)
}
return log
}
/**
* 删除本地打包文件
*/
function removeLocalFile() {
try {
projects.forEach(item => {
fs.unlinkSync(`${ process.cwd() }/${ item.distPath }.zip`)
})
} catch (e) {
error(e)
process.exit(1)
}
}
/**
* 断开ssh连接
*/
function disconnectSSH() {
ssh.dispose()
}