102 lines
3.1 KiB
TypeScript
102 lines
3.1 KiB
TypeScript
import { defineConfig } from 'vite'
|
|
import vue from '@vitejs/plugin-vue'
|
|
import tailwindcss from '@tailwindcss/vite'
|
|
import { viteStaticCopy } from 'vite-plugin-static-copy'
|
|
import { fileURLToPath, URL } from 'node:url'
|
|
import { writeFileSync, readFileSync, readdirSync, statSync, existsSync, unlinkSync } from 'node:fs'
|
|
import { join, resolve } from 'node:path'
|
|
import { gzipSync } from 'node:zlib'
|
|
|
|
// Simple inline compression plugin to avoid extra dependencies
|
|
const compressionPlugin = () => ({
|
|
name: 'compression-plugin',
|
|
apply: 'build',
|
|
closeBundle: {
|
|
order: 'post',
|
|
handler: async () => {
|
|
const distDir = resolve(process.cwd(), 'dist')
|
|
if (!existsSync(distDir)) return
|
|
|
|
const compressDir = (dir: string) => {
|
|
const files = readdirSync(dir)
|
|
for (const file of files) {
|
|
const filePath = join(dir, file)
|
|
const stat = statSync(filePath)
|
|
if (stat.isDirectory()) {
|
|
compressDir(filePath)
|
|
} else if (file.match(/\.(js|css|html|svg|json|vs)$/) && !file.endsWith('.gz')) {
|
|
try {
|
|
const content = readFileSync(filePath)
|
|
if (content.length < 1024) continue // Don't compress very small files
|
|
const gzipped = gzipSync(content, { level: 9 })
|
|
writeFileSync(`${filePath}.gz`, gzipped)
|
|
// Remove original file after successful compression to save space in binary
|
|
unlinkSync(filePath)
|
|
} catch (e) {
|
|
console.error(`Compression failed for ${file}:`, e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
compressDir(distDir)
|
|
}
|
|
}
|
|
} as const)
|
|
|
|
export default defineConfig({
|
|
plugins: [
|
|
vue(),
|
|
tailwindcss(),
|
|
viteStaticCopy({
|
|
targets: [
|
|
{
|
|
src: 'node_modules/monaco-editor/min/vs',
|
|
dest: 'assets'
|
|
}
|
|
]
|
|
}),
|
|
compressionPlugin()
|
|
],
|
|
resolve: {
|
|
alias: {
|
|
'@': fileURLToPath(new URL('./src', import.meta.url))
|
|
}
|
|
},
|
|
server: {
|
|
proxy: {
|
|
'/api': {
|
|
target: 'http://localhost:8052',
|
|
changeOrigin: true,
|
|
ws: true
|
|
},
|
|
'/openapi': {
|
|
target: 'http://localhost:8052',
|
|
changeOrigin: true
|
|
}
|
|
}
|
|
},
|
|
// 使用相对路径,这样动态导入的模块也会使用相对路径
|
|
// 浏览器会根据当前页面 URL 解析相对路径
|
|
base: './',
|
|
build: {
|
|
reportCompressedSize: true,
|
|
sourcemap: false,
|
|
rollupOptions: {
|
|
output: {
|
|
// 防止生成以 _ 开头的文件,导致被 Cloudflare Pages 或 Github Pages 等静态托管平台拦截并降级返回 HTML
|
|
chunkFileNames: 'assets/[name]-[hash].js',
|
|
entryFileNames: 'assets/[name]-[hash].js',
|
|
assetFileNames: 'assets/[name]-[hash].[ext]',
|
|
sanitizeFileName(name) {
|
|
// 仿制 Rollup 的默认 sanitizeFileName,将特殊字符替换为 '-'
|
|
let safeName = name.replace(/[\0?*:|"<>\/\\&=$]/g, '-')
|
|
// 去除开头可能引起静态托管平台屏蔽的下划线 '_'
|
|
return safeName.replace(/^_/, '')
|
|
}
|
|
}
|
|
}
|
|
},
|
|
define: {
|
|
}
|
|
})
|