vite.config.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import path, { resolve } from "path"
  2. import fs from "fs"
  3. import { execSync } from "child_process"
  4. import { defineConfig, type PluginOption, type Plugin } from "vite"
  5. import react from "@vitejs/plugin-react"
  6. import tailwindcss from "@tailwindcss/vite"
  7. import { sourcemapPlugin } from "./src/vite-plugins/sourcemapPlugin"
  8. function getGitSha() {
  9. let gitSha: string | undefined = undefined
  10. try {
  11. gitSha = execSync("git rev-parse HEAD").toString().trim()
  12. } catch (_error) {
  13. // Do nothing.
  14. }
  15. return gitSha
  16. }
  17. const wasmPlugin = (): Plugin => ({
  18. name: "wasm",
  19. async load(id) {
  20. if (id.endsWith(".wasm")) {
  21. const wasmBinary = await import(id)
  22. return `
  23. const wasmModule = new WebAssembly.Module(${wasmBinary.default});
  24. export default wasmModule;
  25. `
  26. }
  27. },
  28. })
  29. const persistPortPlugin = (): Plugin => ({
  30. name: "write-port-to-file",
  31. configureServer(viteDevServer) {
  32. viteDevServer?.httpServer?.once("listening", () => {
  33. const address = viteDevServer?.httpServer?.address()
  34. const port = address && typeof address === "object" ? address.port : null
  35. if (port) {
  36. fs.writeFileSync(resolve(__dirname, "..", ".vite-port"), port.toString())
  37. console.log(`[Vite Plugin] Server started on port ${port}`)
  38. } else {
  39. console.warn("[Vite Plugin] Could not determine server port")
  40. }
  41. })
  42. },
  43. })
  44. // https://vitejs.dev/config/
  45. export default defineConfig(({ mode }) => {
  46. let outDir = "../src/webview-ui/build"
  47. const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "src", "package.json"), "utf8"))
  48. const gitSha = getGitSha()
  49. const define: Record<string, any> = {
  50. "process.platform": JSON.stringify(process.platform),
  51. "process.env.VSCODE_TEXTMATE_DEBUG": JSON.stringify(process.env.VSCODE_TEXTMATE_DEBUG),
  52. "process.env.PKG_NAME": JSON.stringify(pkg.name),
  53. "process.env.PKG_VERSION": JSON.stringify(pkg.version),
  54. "process.env.PKG_OUTPUT_CHANNEL": JSON.stringify("Roo-Code"),
  55. ...(gitSha ? { "process.env.PKG_SHA": JSON.stringify(gitSha) } : {}),
  56. }
  57. // TODO: We can use `@roo-code/build` to generate `define` once the
  58. // monorepo is deployed.
  59. if (mode === "nightly") {
  60. outDir = "../apps/vscode-nightly/build/webview-ui/build"
  61. const nightlyPkg = JSON.parse(
  62. fs.readFileSync(path.join(__dirname, "..", "apps", "vscode-nightly", "package.nightly.json"), "utf8"),
  63. )
  64. define["process.env.PKG_NAME"] = JSON.stringify(nightlyPkg.name)
  65. define["process.env.PKG_VERSION"] = JSON.stringify(nightlyPkg.version)
  66. define["process.env.PKG_OUTPUT_CHANNEL"] = JSON.stringify("Roo-Code-Nightly")
  67. }
  68. const plugins: PluginOption[] = [react(), tailwindcss(), persistPortPlugin(), wasmPlugin(), sourcemapPlugin()]
  69. return {
  70. plugins,
  71. resolve: {
  72. alias: {
  73. "@": resolve(__dirname, "./src"),
  74. "@src": resolve(__dirname, "./src"),
  75. "@roo": resolve(__dirname, "../src/shared"),
  76. },
  77. },
  78. build: {
  79. outDir,
  80. emptyOutDir: true,
  81. reportCompressedSize: false,
  82. // Generate complete source maps with original TypeScript sources
  83. sourcemap: true,
  84. // Ensure source maps are properly included in the build
  85. minify: mode === "production" ? "esbuild" : false,
  86. rollupOptions: {
  87. output: {
  88. entryFileNames: `assets/[name].js`,
  89. chunkFileNames: (chunkInfo) => {
  90. if (chunkInfo.name === "mermaid-bundle") {
  91. return `assets/mermaid-bundle.js`
  92. }
  93. // Default naming for other chunks, ensuring uniqueness from entry
  94. return `assets/chunk-[hash].js`
  95. },
  96. assetFileNames: (assetInfo) => {
  97. if (
  98. assetInfo.name &&
  99. (assetInfo.name.endsWith(".woff2") ||
  100. assetInfo.name.endsWith(".woff") ||
  101. assetInfo.name.endsWith(".ttf"))
  102. ) {
  103. return "assets/fonts/[name][extname]"
  104. }
  105. // Ensure source maps are included in the build
  106. if (assetInfo.name && assetInfo.name.endsWith(".map")) {
  107. return "assets/[name]"
  108. }
  109. return "assets/[name][extname]"
  110. },
  111. manualChunks: (id, { getModuleInfo }) => {
  112. // Consolidate all mermaid code and its direct large dependencies (like dagre)
  113. // into a single chunk. The 'channel.js' error often points to dagre.
  114. if (
  115. id.includes("node_modules/mermaid") ||
  116. id.includes("node_modules/dagre") || // dagre is a common dep for graph layout
  117. id.includes("node_modules/cytoscape") // another potential graph lib
  118. // Add other known large mermaid dependencies if identified
  119. ) {
  120. return "mermaid-bundle"
  121. }
  122. // Check if the module is part of any explicitly defined mermaid-related dynamic import
  123. // This is a more advanced check if simple path matching isn't enough.
  124. const moduleInfo = getModuleInfo(id)
  125. if (moduleInfo?.importers.some((importer) => importer.includes("node_modules/mermaid"))) {
  126. return "mermaid-bundle"
  127. }
  128. if (
  129. moduleInfo?.dynamicImporters.some((importer) => importer.includes("node_modules/mermaid"))
  130. ) {
  131. return "mermaid-bundle"
  132. }
  133. },
  134. },
  135. },
  136. },
  137. server: {
  138. hmr: {
  139. host: "localhost",
  140. protocol: "ws",
  141. },
  142. cors: {
  143. origin: "*",
  144. methods: "*",
  145. allowedHeaders: "*",
  146. },
  147. },
  148. define,
  149. optimizeDeps: {
  150. include: [
  151. "mermaid",
  152. "dagre", // Explicitly include dagre for pre-bundling
  153. // Add other known large mermaid dependencies if identified
  154. ],
  155. exclude: ["@vscode/codicons", "vscode-oniguruma", "shiki"],
  156. },
  157. assetsInclude: ["**/*.wasm", "**/*.wav"],
  158. }
  159. })