import { defineConfig, loadEnv } from 'vite' import uni from '@dcloudio/vite-plugin-uni' import path from 'path' import fs from 'node:fs' import type { Plugin } from 'vite' import { STATIC_ASSETS_BASE_URL_PRODUCTION, STATIC_ASSETS_BASE_URL_TEST } from './src/config/static-assets-defaults' function normalizeStaticBase(url: string): string { const u = url.trim() if (!u) return STATIC_ASSETS_BASE_URL_TEST return u.endsWith('/') ? u : `${u}/` } function resolveStaticBaseFromViteEnv(mode: string, env: Record): string { const explicit = env.VITE_STATIC_ASSETS_BASE_URL?.trim() if (explicit) return normalizeStaticBase(explicit) return normalizeStaticBase(mode === 'production' ? STATIC_ASSETS_BASE_URL_PRODUCTION : STATIC_ASSETS_BASE_URL_TEST) } const TABBAR_PLACEHOLDER = '__STATIC_ASSETS_BASE_URL__' /** pages.json 中 tabBar 图标占位符:开发 / H5 构建时替换为真实根地址,与 scripts/pages-tabbar-migrate.mjs 行为一致 */ function pagesJsonTabbarPlugin(staticAssetsBase: string, root: string): Plugin { const pagesPath = path.join(root, 'src/pages.json') const bakPath = path.join(root, 'src/.pages-json.tabbar-placeholder.bak') let isServe = false /** 避免 dev 关闭时 close / 信号 重复还原 */ let devShutdownDone = false function materialize() { const raw = fs.readFileSync(pagesPath, 'utf8') if (!raw.includes(TABBAR_PLACEHOLDER)) return fs.writeFileSync(bakPath, raw, 'utf8') const base = normalizeStaticBase(staticAssetsBase) fs.writeFileSync(pagesPath, raw.replace(new RegExp(TABBAR_PLACEHOLDER, 'g'), base), 'utf8') } /** 从备份还原占位符版本;无备份则跳过(幂等,可多次调用) */ function restore() { if (!fs.existsSync(bakPath)) return fs.copyFileSync(bakPath, pagesPath) fs.unlinkSync(bakPath) } return { name: 'pages-json-tabbar-static-base', configResolved(config) { isServe = config.command === 'serve' }, buildStart() { if (!isServe) materialize() }, buildEnd() { if (!isServe) restore() }, configureServer(server) { materialize() const onShutdown = () => { if (devShutdownDone) return devShutdownDone = true restore() } server.httpServer?.once('close', onShutdown) process.once('SIGINT', onShutdown) process.once('SIGTERM', onShutdown) } } } export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), '') const staticAssetsBase = resolveStaticBaseFromViteEnv(mode, env) return { plugins: [ uni(), pagesJsonTabbarPlugin(staticAssetsBase, __dirname), { name: 'replace-static-assets-base-in-html', transformIndexHtml(html) { return html.replace(/__STATIC_ASSETS_BASE_URL__/g, staticAssetsBase) } } ], resolve: { alias: { '@': path.resolve(__dirname, 'src') } }, css: { preprocessorOptions: { scss: { additionalData: '@import "@/styles/variables.scss";' } } } } })