vite.config.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import path from "path"
  2. import { readFileSync } from "fs"
  3. import { defineConfig } from "vitest/config"
  4. import react from "@vitejs/plugin-react"
  5. import tailwindcss from "@tailwindcss/vite"
  6. import { sentryVitePlugin } from "@sentry/vite-plugin"
  7. const host = process.env.TAURI_DEV_HOST
  8. // Read version from package.json at config-load time so the Settings
  9. // UI can show the running app version without duplicating the string.
  10. const pkgJson = JSON.parse(readFileSync(path.resolve(import.meta.dirname, "package.json"), "utf-8"))
  11. const sentryRelease = `qmai@${pkgJson.version}`
  12. const sentryAuthToken = process.env.SENTRY_AUTH_TOKEN
  13. const uploadSentrySourcemaps = Boolean(sentryAuthToken)
  14. // https://vitejs.dev/config/
  15. export default defineConfig({
  16. plugins: [
  17. react(),
  18. tailwindcss(),
  19. // Last plugin. No token → no maps, no upload (local / CI check).
  20. sentryVitePlugin({
  21. disable: !uploadSentrySourcemaps,
  22. org: process.env.SENTRY_ORG || "qmai-c5",
  23. project: process.env.SENTRY_PROJECT || "qmai",
  24. authToken: sentryAuthToken,
  25. telemetry: false,
  26. release: { name: sentryRelease },
  27. sourcemaps: {
  28. filesToDeleteAfterUpload: ["./dist/**/*.map"],
  29. },
  30. }),
  31. ],
  32. resolve: {
  33. alias: { "@": path.resolve(import.meta.dirname, "./src") },
  34. },
  35. define: {
  36. __APP_VERSION__: JSON.stringify(pkgJson.version),
  37. __BUILD_TIME__: JSON.stringify(new Date().toISOString()),
  38. },
  39. // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
  40. //
  41. // 1. prevent vite from obscuring rust errors
  42. clearScreen: false,
  43. build: {
  44. // Hidden maps only when uploading; never ship *.map in the Tauri bundle.
  45. sourcemap: uploadSentrySourcemaps ? "hidden" : false,
  46. chunkSizeWarningLimit: 700,
  47. modulePreload: {
  48. resolveDependencies(_filename: string, deps: string[]) {
  49. return deps.filter((dep) => !dep.includes("graphology-vendor"))
  50. },
  51. },
  52. rollupOptions: {
  53. output: {
  54. manualChunks(id: string) {
  55. if (id.includes("node_modules")) {
  56. if (id.includes("opencc-js")) {
  57. return "opencc-vendor"
  58. }
  59. if (id.includes("pinyin-pro")) {
  60. return "pinyin-vendor"
  61. }
  62. if (id.includes("js-yaml")) {
  63. return "yaml-vendor"
  64. }
  65. if (id.includes("@react-sigma") || id.includes("sigma")) {
  66. return "sigma-vendor"
  67. }
  68. if (id.includes("graphology")) {
  69. return "graphology-vendor"
  70. }
  71. if (id.includes("react") || id.includes("scheduler")) {
  72. return "react-vendor"
  73. }
  74. if (id.includes("@milkdown")) {
  75. return "milkdown-vendor"
  76. }
  77. if (id.includes("katex") || id.includes("remark-math") || id.includes("rehype-katex")) {
  78. return "katex-vendor"
  79. }
  80. if (id.includes("cytoscape")) {
  81. return "cytoscape-vendor"
  82. }
  83. }
  84. return undefined
  85. },
  86. },
  87. },
  88. },
  89. // 2. tauri expects a fixed port, fail if that port is not available
  90. server: {
  91. port: 1420,
  92. strictPort: true,
  93. host: host || false,
  94. hmr: host
  95. ? {
  96. protocol: "ws",
  97. host,
  98. port: 1421,
  99. }
  100. : undefined,
  101. watch: {
  102. ignored: [
  103. "**/src-tauri/**",
  104. "**/node_modules/**",
  105. "**/dist/**",
  106. "**/.vite/**",
  107. "**/.novel/**",
  108. "**/chapters/**",
  109. "**/wiki/**",
  110. "**/target/**",
  111. "**/*.snapshot.*",
  112. "**/*.json",
  113. "**/*.store",
  114. ],
  115. },
  116. },
  117. test: {
  118. environment: "node",
  119. // Loads .env.test.local into process.env for real-LLM tests.
  120. // The loader itself is a no-op if the file is absent, so this is
  121. // safe to keep on for every test run.
  122. setupFiles: ["./src/test-helpers/load-test-env.ts"],
  123. exclude: [
  124. "**/node_modules/**",
  125. "**/dist/**",
  126. "**/cypress/**",
  127. "**/.{idea,git,cache,output,temp}/**",
  128. "**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*",
  129. "**/.worktrees/**",
  130. ],
  131. },
  132. })