deploy.js

This commit is contained in:
洛洛希雅 2024-04-25 08:48:20 +08:00
parent 64766795bb
commit 0fd5edd0f3
3 changed files with 150 additions and 2 deletions

125
deploy.js Normal file
View File

@ -0,0 +1,125 @@
/**
* $description
* @author 一七年夏
* @since 2022-12-07 14:00
*/
'use strict'
const childProcess = require('child_process')
const SSH2Promise = require('ssh2-promise')
const fs = require('fs')
const { v4 } = require('uuid')
const { zip } = require('compressing')
const dialog = require('dialog')
const delay = (ms) => new Promise((r) => setTimeout(r, ms))
const sshConfig = {
host: 'clould.lolosia.top',
port: 22,
username: 'lolosia',
password: 'lolo2024.'
}
const tempDir = '/home/lolosia/nginx/cache'
const tempPrefix = 'home'
const nginxContentPath = 'home'
async function localExec(cmd) {
return new Promise((r, rj) => {
const process1 = childProcess.exec(cmd)
process1.on('exit', r)
process1.on('error', rj)
process1.stdout.pipe(process.stdout)
process1.stderr.pipe(process.stderr)
})
}
async function main() {
if (!process.argv.includes('-r')) {
console.log('项目构建...')
console.log('前端构建耗时较长,你可以去做其他事,稍后本脚本会弹窗提醒完成。')
await localExec('.\\node_modules\\.bin\\vite build --mode build')
console.log('构建zip...')
await zip.compressDir(`./dist`, './archive.zip')
console.log('连接至服务器...')
} else {
console.log('重新推送...')
}
const ssh2 = new SSH2Promise(sshConfig)
await ssh2.connect()
const ftp = ssh2.sftp()
async function exec(cmd) {
console.log(`运行 ${cmd} ...`)
console.log(await ssh2.exec(cmd))
}
async function sudo(cmd) {
const shell = await ssh2.shell()
shell.stdout.pipe(process.stdout)
shell.stderr.pipe(process.stderr)
process.stdin.pipe(shell.stdin)
shell.write(`sudo ${cmd}\n`)
await delay(500)
shell.write(`${sshConfig.password}\n`)
await delay(1000)
shell.write('exit\n')
await new Promise((resolve) => {
shell.on('end', resolve)
})
process.stdin.unpipe(shell.stdin)
}
async function write(path, text) {
const stream = await ftp.createWriteStream(path, { encoding: 'utf-8' })
return new Promise((r) => {
stream.write(text)
stream.end(r)
})
}
const dir = tempDir
await exec(`mkdir -p ${dir}`)
const archivePath = `${dir}/archive.zip`
console.log(`删除 ${archivePath} ...`)
try {
await ftp.unlink(archivePath)
// eslint-disable-next-line no-empty
} catch (e) {}
console.log(`写入 ${archivePath} ...`)
const stream = await ftp.createWriteStream(archivePath, {
encoding: 'binary'
})
const file = fs.createReadStream('./archive.zip', {
encoding: 'binary',
autoClose: true
})
await new Promise((r, rj) => {
// file.on('close', () => stream.end());
stream.on('finish', () => r())
file.on('end', () => r())
file.on('error', rj)
stream.on('error', rj)
file.pipe(stream)
})
console.log(`写入 ${archivePath} 完成`)
const uuid = v4()
const target = `${dir}/${tempPrefix}-${uuid}`
//if (process.platform === 'win32') {
// await exec(`unzip -O gbk ${archivePath} -d ${target}`)
//} else {
await exec(`unzip ${archivePath} -d ${target}`)
await exec(`mv ${target}/dist ${target}/iGame`)
//}
const nginxTarget = '/home/lolosia/nginx/home'
console.log('移除旧目录 ...')
await sudo(`rm -rf ${nginxTarget}/${nginxContentPath}`)
console.log('复制文件 到指定目录 ...')
await sudo(`cp -r -f ${target}/* ${nginxTarget}`)
await new Promise((r) => {
dialog.info(`你现在可以关闭终端,去做其他事情了`, `${nginxContentPath}项目部署完成!`, r)
})
}
main()
.catch((e) => console.error(e))
.finally(() => process.exit(0))

View File

@ -72,6 +72,8 @@
"@vue/cli-service": "^5.0.8", "@vue/cli-service": "^5.0.8",
"@vue/test-utils": "^2.4.5", "@vue/test-utils": "^2.4.5",
"@vueuse/core": "^10.9.0", "@vueuse/core": "^10.9.0",
"compressing": "^1.10.0",
"dialog": "^0.3.1",
"ejs": "^3.1.9", "ejs": "^3.1.9",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"eslint-config-prettier": "8.5.0", "eslint-config-prettier": "8.5.0",
@ -91,6 +93,7 @@
"resize-observer-polyfill": "^1.5.1", "resize-observer-polyfill": "^1.5.1",
"rollup-plugin-visualizer": "^5.12.0", "rollup-plugin-visualizer": "^5.12.0",
"sass": "^1.72.0", "sass": "^1.72.0",
"ssh2-promise": "^1.0.3",
"svg-sprite-loader": "6.0.11", "svg-sprite-loader": "6.0.11",
"terser": "^5.29.2", "terser": "^5.29.2",
"typescript": "^5.4.3", "typescript": "^5.4.3",

View File

@ -1,6 +1,6 @@
import { resolve } from 'path' import { resolve } from 'path'
import { ConfigEnv, defineConfig, loadEnv, ServerOptions, UserConfig } from 'vite' import { ConfigEnv, defineConfig, loadEnv, ServerOptions, UserConfig } from 'vite'
import vue from '@vitejs/plugin-vue' import vue, { parseVueRequest } from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx' import vueJsx from '@vitejs/plugin-vue-jsx'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import { ViteMockOptions, viteMockServe } from 'vite-plugin-mock' import { ViteMockOptions, viteMockServe } from 'vite-plugin-mock'
@ -94,13 +94,33 @@ export default defineConfig(({ command, mode }: ConfigEnv): UserConfig => {
}), }),
vitePluginSetupExtend({ inject: { title: setting.title } }), vitePluginSetupExtend({ inject: { title: setting.title } }),
vitePluginVueSetupExtend() vitePluginVueSetupExtend(),
//依赖分析插件 //依赖分析插件
// visualizer({ // visualizer({
// open: true, // open: true,
// gzipSize: true, // gzipSize: true,
// brotliSize: true // brotliSize: true
// }) // })
{
name: 'index-transform',
transform(code, id) {
const { filename } = parseVueRequest(id)
if (!filename.includes('vite/preload-helper')) return code
const fn = 'export const __vitePreload'
const index = code.indexOf(fn)
const head = code
.slice(0, index)
.split(';')
.map((it) => `${it};`)
const preload = code.slice(index)
const assetsURLIndex = head.findIndex((it) => it.startsWith('const assetsURL'))
let assetsURL = head[assetsURLIndex]
assetsURL = assetsURL.replace(' return ', " return (window.NGINX_BASE_URL || '') + ")
head[assetsURLIndex] = assetsURL
return [...head, preload].join('\n')
}
}
], ],
build: { build: {
chunkSizeWarningLimit: 10000, //消除触发警告的 chunk, 默认500k chunkSizeWarningLimit: 10000, //消除触发警告的 chunk, 默认500k