vite.config.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { defineConfig, loadEnv } from 'vite'
  2. import uni from '@dcloudio/vite-plugin-uni'
  3. import path from 'path'
  4. import fs from 'node:fs'
  5. import type { Plugin } from 'vite'
  6. import {
  7. STATIC_ASSETS_BASE_URL_PRODUCTION,
  8. STATIC_ASSETS_BASE_URL_TEST
  9. } from './src/config/static-assets-defaults'
  10. function normalizeStaticBase(url: string): string {
  11. const u = url.trim()
  12. if (!u) return STATIC_ASSETS_BASE_URL_TEST
  13. return u.endsWith('/') ? u : `${u}/`
  14. }
  15. function resolveStaticBaseFromViteEnv(mode: string, env: Record<string, string>): string {
  16. const explicit = env.VITE_STATIC_ASSETS_BASE_URL?.trim()
  17. if (explicit) return normalizeStaticBase(explicit)
  18. return normalizeStaticBase(mode === 'production' ? STATIC_ASSETS_BASE_URL_PRODUCTION : STATIC_ASSETS_BASE_URL_TEST)
  19. }
  20. const TABBAR_PLACEHOLDER = '__STATIC_ASSETS_BASE_URL__'
  21. /** pages.json 中 tabBar 图标占位符:开发 / H5 构建时替换为真实根地址,与 scripts/pages-tabbar-migrate.mjs 行为一致 */
  22. function pagesJsonTabbarPlugin(staticAssetsBase: string, root: string): Plugin {
  23. const pagesPath = path.join(root, 'src/pages.json')
  24. const bakPath = path.join(root, 'src/.pages-json.tabbar-placeholder.bak')
  25. let isServe = false
  26. /** 避免 dev 关闭时 close / 信号 重复还原 */
  27. let devShutdownDone = false
  28. function materialize() {
  29. const raw = fs.readFileSync(pagesPath, 'utf8')
  30. if (!raw.includes(TABBAR_PLACEHOLDER)) return
  31. fs.writeFileSync(bakPath, raw, 'utf8')
  32. const base = normalizeStaticBase(staticAssetsBase)
  33. fs.writeFileSync(pagesPath, raw.replace(new RegExp(TABBAR_PLACEHOLDER, 'g'), base), 'utf8')
  34. }
  35. /** 从备份还原占位符版本;无备份则跳过(幂等,可多次调用) */
  36. function restore() {
  37. if (!fs.existsSync(bakPath)) return
  38. fs.copyFileSync(bakPath, pagesPath)
  39. fs.unlinkSync(bakPath)
  40. }
  41. return {
  42. name: 'pages-json-tabbar-static-base',
  43. configResolved(config) {
  44. isServe = config.command === 'serve'
  45. },
  46. buildStart() {
  47. if (!isServe) materialize()
  48. },
  49. buildEnd() {
  50. if (!isServe) restore()
  51. },
  52. configureServer(server) {
  53. materialize()
  54. const onShutdown = () => {
  55. if (devShutdownDone) return
  56. devShutdownDone = true
  57. restore()
  58. }
  59. server.httpServer?.once('close', onShutdown)
  60. process.once('SIGINT', onShutdown)
  61. process.once('SIGTERM', onShutdown)
  62. }
  63. }
  64. }
  65. export default defineConfig(({ mode }) => {
  66. const env = loadEnv(mode, process.cwd(), '')
  67. const staticAssetsBase = resolveStaticBaseFromViteEnv(mode, env)
  68. return {
  69. plugins: [
  70. uni(),
  71. pagesJsonTabbarPlugin(staticAssetsBase, __dirname),
  72. {
  73. name: 'replace-static-assets-base-in-html',
  74. transformIndexHtml(html) {
  75. return html.replace(/__STATIC_ASSETS_BASE_URL__/g, staticAssetsBase)
  76. }
  77. }
  78. ],
  79. resolve: {
  80. alias: {
  81. '@': path.resolve(__dirname, 'src')
  82. }
  83. },
  84. css: {
  85. preprocessorOptions: {
  86. scss: {
  87. additionalData: '@import "@/styles/variables.scss";'
  88. }
  89. }
  90. }
  91. }
  92. })