环境准备:
"node": "^18.15",
"pnpm": "^8",
"vite": "^5.0.10",
"typescript": "^5.3.3",
"chalk": "^5.3.0",
"dayjs": "^1.11.9",
部署脚本:
import { cp, rm, rename } from 'node:fs/promises'
import path from 'node:path'
import Ora from 'ora'
import chalk from 'chalk'
import { spawn, spawnSync } from 'node:child_process'
import dayjs from 'dayjs'
const ora = Ora()
const envName = process.argv[2] // 58 || 59 || prod
let now = 0
const succeed = () => {
ora.succeed(ora.text + chalk.green(` [${(Date.now() - now) / 1000}s]`))
}
ora.info('环境名:' + chalk.blue('.env.' + envName))
try {
const branchName = spawnSync('git branch --show-current', { shell: true })
.stdout.toString()
.replaceAll('\n', '')
ora.info('分支名:' + chalk.blue(branchName))
} catch (e) {
ora.warn('分支名:' + chalk.red(`[获取失败]`))
}
const tasks = [
{
text: 'pnpm安装插件',
command: ['pnpm', ['install']],
},
{
text: 'ts类型检测',
command: ['npx', ['vue-tsc']],
},
{
text: 'vite打包',
command: ['npx', ['vite', 'build', '--mode', envName]],
},
]
for (let i = 0; i < tasks.length; ++i) {
const task = tasks[i]
await new Promise((resolve, reject) => {
/**
* @type {ChildProcessWithoutNullStreams}
*/
const stream = spawn.apply(null, task.command.concat({ stdio: 'pipe', shell: true }))
ora.start(task.text)
now = Date.now()
let totalText = ''
stream.stdout.on('data', (chunk) => {
totalText += chunk.toString()
ora.text = task.text + ' ' + chalk.gray(chunk.toString().split('\n')[0])
})
stream
.on('error', (err) => {
ora.text = task.text
// 异常
ora.fail()
reject(err)
})
.on('close', (code) => {
ora.text = task.text
if (code === 0) {
succeed()
resolve()
} else {
// 不属于异常,就是退出码不一样
ora.fail()
console.log('\n', totalText)
process.exit(code)
}
})
})
}
ora.info('开始部署')
try {
const localDist = path.resolve('dist')
let remoteDir
switch (envName) {
case '58':
remoteDir = '\\\\xx\\58_frontend'
break
case '59':
remoteDir = '\\\\10.56.66.58\\xx\\59_frontend'
break
case 'prod':
remoteDir = '\\\\xx\\frontend'
break
default:
throw new Error('未找到部署服务器')
}
const remoteTmpDist = path.join(remoteDir, '.dist-tmp')
const remoteDist = path.join(remoteDir, envName === 'prod' ? 'rdup_dist' : 'dist')
{
now = Date.now()
ora.start('上传dist目录')
await rm(remoteTmpDist, { recursive: true, force: true })
await cp(localDist, remoteTmpDist, { recursive: true, force: true })
succeed()
}
now = Date.now()
if (envName === 'prod') {
ora.start('合并远程目录:' + remoteDist)
await cp(
path.join(remoteDist, 'index.html'),
path.join(remoteDist, 'index.html.' + dayjs().format('YYYYMMDD_HHmmss')),
)
await cp(remoteTmpDist, remoteDist, { recursive: true, force: true })
} else {
ora.start('替换远程目录:' + remoteDist)
await rm(remoteDist, { recursive: true, force: true })
await rename(remoteTmpDist, remoteDist)
}
succeed()
} catch (e) {
if (e.code === 'EPERM') {
ora.fail(ora.text + chalk.red(' [权限不足]'))
process.exit(0)
} else {
throw e
}
}
ora.succeed('部署结束')
效果如下:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。