-
第一种方式: gulp 打包后的文件上传至服务器
下载:
package.json:npm install -D gulp-sftp-up4 gulp-ssh
"scripts": { "server-dev": "cross-env NODE_ENV=dev gulp default },
const { task, src, series } = require('gulp'); const sftp = require('gulp-sftp-up4'); const devConfig = { host: '119.23.**.***', port: 888, user: 'root', pass: '****', remotePath: '/usr/local/nginx/html/test' } const testConfig = { host: '47.106.***.***', port: 888, user: 'root', pass: '****', remotePath: '/usr/local/nginx/html/webapps/test' } const gulpConfig = process.env.NODE_ENV === 'dev' ? devConfig : testConfig task('upload', function (done) { return src('./build/**') .pipe(sftp(gulpConfig)); }) task('default', series('upload'));
-
第二种方式: node 打包
打包、压缩、删除源代码、上传 一条龙。
效果:
前端命令上传服务器
1、commander : 在执行的时候增加参数,判断环境
const { program } = require('commander');
program
.option('-c, --cheese <type>', 'add the specified type of cheese', 'blue'); // 默认值 blue
program.parse(process.argv);
console.log(`cheese: ${program.cheese}`);
终端执行node:
--cheese
得到结果: cheese: blue
--cheese green
得到结果: cheese: green
2、ora:处理终端转轮状态
成功、失败、运行中等状态
ora 优雅的终端转轮
const ora = require('ora')
ora().fail('请配置部署环境')
如图显示:
3、inquirer:用户与命令行交互
询问是否进行环境的部署:
const inquirer = require('inquirer')
const answer = await inquirer.prompt([{
type: 'confirm',
message: '是否进行部署?',
name: 'confirm', // 交互的关键字,如果有多条数据可以在这边获取到
}])
console.log("answer", answer.confirm)
const chalk = require('chalk')
const ora = require('ora')
// 成功信息
const succeed = (message) => {
ora().succeed(chalk.greenBright.bold(message))
}
// 提示信息
const info = (message) => {
ora().info(chalk.blueBright.bold(message))
}
// 错误信息
const error = (message) => {
ora().fail(chalk.redBright.bold(message))
}
// 下划线重点信息
const underline = (message) => {
return chalk.underline.blueBright.bold(message)
}
// 使用
succeed("成功啦~~~")
error("失败了- -")
info(`提示 。。。${underline("下划线* *")}`)
// 执行打包
const childProcess = require('child_process');
const maxBuffer = 5120 * 1024
const ora = require('ora')
function execBuild() {
const spinner = ora('正在打包中...\n')
spinner.start()
return new Promise((resolve, reject) => {
childProcess.exec('yarn build', {
cwd: process.cwd(),
maxBuffer: maxBuffer,
}, (error, stdout, stderr) => {
spinner.stop()
if (error) {
error(`打包出错: ${error}`)
reject(error)
return;
}
succeed('打包成功')
resolve(stdout)
})
})
}
const { program } = require('commander')
const chalk = require('chalk')
const ora = require('ora')
const inquirer = require('inquirer')
const childProcess = require('child_process')
const fs = require('fs')
const archiver = require('archiver')
const { NodeSSH } = require('node-ssh')
const ssh = new NodeSSH()
const maxBuffer = 5120 * 1024
let taskList = [] // 任务队列
const config = {
dev: {
host: '119.23.**.***',
port: 888,
username: 'root',
password: '****',
local: 'build',
remote: '/usr/local/nginx/html/test', // 服务器部署路径(不可为空或'/')
script: 'yarn build',
},
test: {
host: '47.106.**.***',
port: 888,
username: 'root',
password: '****',
local: 'build',
remote: '/usr/local/nginx/html/test', // 服务器部署路径(不可为空或'/')
script: 'yarn build',
}
}
// 成功信息
const succeed = (message) => {
ora().succeed(chalk.greenBright.bold(message))
}
// 提示信息
const info = (message) => {
ora().info(chalk.blueBright.bold(message))
}
// 错误信息
const error = (message) => {
ora().fail(chalk.redBright.bold(message))
}
// 下划线重点信息
const underline = (message) => {
return chalk.underline.blueBright.bold(message)
}
// 执行打包
async function execBuild(sshConfig, index) {
const spinner = ora('正在打包中...\n')
spinner.start()
const { script } = sshConfig
return new Promise((resolve, reject) => {
childProcess.exec(script, {
cwd: process.cwd(),
maxBuffer: maxBuffer,
}, (error, stdout, stderr) => {
spinner.stop()
if (error) {
error(`打包出错: ${error}`)
reject(error)
return;
}
succeed(`${index}. 打包成功`)
resolve(stdout)
})
})
}
// 压缩文件
async function buildZip(sshConfig, index) {
const { local } = sshConfig
return new Promise((resolve, reject) => {
const output = fs.createWriteStream(`${process.cwd()}/${local}.zip`);
const archive = archiver('zip', {
zlib: { level: 9 } // Sets the compression level.
});
output.on('close', function (e) {
if (e) {
error(`压缩失败${e}`)
reject(e)
} else {
succeed(`${index}. 压缩成功`)
resolve()
}
});
archive.pipe(output);
archive.directory(local, false)
archive.finalize();
})
}
// 连接服务器
async function connectSSH(sshConfig, index) {
try {
await ssh.connect(sshConfig)
succeed(`${index}. ssh连接成功`)
} catch (e) {
error('连接失败')
process.exit(1)
}
}
// 上传文件
async function putFileRemote(sshConfig, index) {
try {
const { local, remote } = sshConfig
const spinner = ora('正在上传中...\n')
spinner.start()
await ssh.putFile(`${process.cwd()}/${local}.zip`, `${remote}.zip`, null, { concurrency: 1 })
spinner.stop()
succeed(`${index}. 文件成功上传ssh`)
} catch (e) {
console.log(e)
error(`文件上传ssh失败${e}`)
process.exit(1)
}
}
// 删除服务端文件
async function removeRemoteFile(sshConfig, index) {
try {
const { local, remote } = sshConfig
const spinner = ora('正在删除服务端文件中...\n')
spinner.start()
await ssh.execCommand(`rm -rf ${remote}/static`)
spinner.stop()
succeed(`${index}. 删除服务端文件成功`)
} catch (e) {
error(`删除服务端文件失败${e}`)
process.exit(1)
}
}
// 解压服务端文件
async function unzipRemoteFile(sshConfig, index) {
try {
const { local, remote } = sshConfig
const zipFileName = `${remote}.zip`
const spinner = ora('正在解压服务端文件中...\n')
spinner.start()
await ssh.execCommand(`unzip -o ${zipFileName} -d ${remote} && rm -rf ${zipFileName}`)
spinner.stop()
succeed(`${index}. 解压服务端文件成功`)
} catch (e) {
error(`解压服务端文件失败${e}`)
process.exit(1)
}
}
// 删除本地文件
async function removeLocalFile(sshConfig, index) {
try {
const { local } = sshConfig
const localFileName = `${local}.zip`
await fs.unlinkSync(localFileName)
succeed(`${index}. 删除本地文件成功`)
} catch (e) {
error(`删除本地文件失败${e}`)
process.exit(1)
}
}
// 断开连接
async function disconnectSSH(sshConfig, index) {
try {
await ssh.dispose()
succeed(`${index}. 成功断开连接`)
} catch (e) {
error(`断开连接失败${e}`)
process.exit(1)
}
}
// 任务执行队列
function handleTaskList() {
taskList.push(execBuild)
taskList.push(buildZip)
taskList.push(connectSSH)
taskList.push(putFileRemote)
taskList.push(removeRemoteFile)
taskList.push(unzipRemoteFile)
taskList.push(removeLocalFile)
taskList.push(disconnectSSH)
}
// 执行任务队列
async function executeTaskList(sshConfig) {
for (let index = 0; index < taskList.length; index++) {
const exectue = taskList[index];
await exectue(sshConfig, index + 1)
}
}
// 检查环境配置
function checkEnvCorrect(sshConfig, mode) {
const keys = [,
'host',
'port',
'username',
'password',
'local',
'remote',
'script'
]
keys.forEach((item) => {
const key = sshConfig[item]
if (!key || key === '/') {
error(`配置错误: ${underline(`${mode}环境`)} ${underline(`${item}属性`)} 配置不正确`)
process.exit(1)
}
})
}
const main = async (mode) => {
if (mode) {
const answer = await inquirer.prompt([{
type: 'confirm',
message: '是否进行部署?',
name: 'confirm', // 交互的关键字,如果有多条数据可以在这边获取到
}])
const currentTime = new Date().getTime()
if (answer.confirm) {
const sshConfig = config[mode]
checkEnvCorrect(sshConfig, mode)
handleTaskList()
await executeTaskList(sshConfig)
const nowTime = new Date().getTime()
succeed(`????????????恭喜,项目部署成功,耗时${(nowTime - currentTime) / 1000}s \n`)
process.exit(0)
} else {
info('取消部署')
}
} else {
error('请配置部署环境 --mode')
process.exit(1)
}
}
program
.option('-m, --mode <type>', 'add the specified type of dev', 'dev')
.action((options) => {
// console.log(options.mode);
main(options.mode)
});;
program.parse(process.argv);