sourcemapPlugin.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import { Plugin } from "vite"
  2. import fs from "fs"
  3. import path from "path"
  4. /**
  5. * Custom Vite plugin to ensure source maps are properly included in the build
  6. * This plugin copies source maps to the build directory and ensures they're accessible
  7. */
  8. export function sourcemapPlugin(): Plugin {
  9. return {
  10. name: "vite-plugin-sourcemap",
  11. apply: "build",
  12. // After the build is complete, ensure source maps are included in the build
  13. closeBundle: {
  14. order: "post",
  15. handler: async () => {
  16. console.log("Ensuring source maps are included in build...")
  17. // Determine the correct output directory based on the build mode
  18. const mode = process.env.NODE_ENV
  19. let outDir
  20. if (mode === "nightly") {
  21. outDir = path.resolve("../apps/vscode-nightly/build/webview-ui/build")
  22. } else {
  23. outDir = path.resolve("../src/webview-ui/build")
  24. }
  25. const assetsDir = path.join(outDir, "assets")
  26. console.log(`Source map processing for ${mode} build in ${outDir}`)
  27. // Check if build directory exists
  28. if (!fs.existsSync(outDir)) {
  29. console.warn("Build directory not found:", outDir)
  30. return
  31. }
  32. // Check if assets directory exists
  33. if (!fs.existsSync(assetsDir)) {
  34. console.warn("Assets directory not found:", assetsDir)
  35. return
  36. }
  37. // Find JS files in the assets directory
  38. const jsFiles = fs.readdirSync(assetsDir).filter((file) => file.endsWith(".js"))
  39. console.log(`Found ${jsFiles.length} JS files in assets directory`)
  40. // Check for source maps
  41. for (const jsFile of jsFiles) {
  42. const jsPath = path.join(assetsDir, jsFile)
  43. const mapPath = jsPath + ".map"
  44. // If source map exists, ensure it's properly referenced in the JS file
  45. if (fs.existsSync(mapPath)) {
  46. console.log(`Source map found for ${jsFile}`)
  47. // Read the JS file
  48. let jsContent = fs.readFileSync(jsPath, "utf8")
  49. // Check if the source map is already referenced
  50. if (!jsContent.includes("//# sourceMappingURL=")) {
  51. console.log(`Adding source map reference to ${jsFile}`)
  52. // Add source map reference
  53. jsContent += `\n//# sourceMappingURL=${jsFile}.map\n`
  54. // Write the updated JS file
  55. fs.writeFileSync(jsPath, jsContent)
  56. }
  57. // Make sure map file is in the correct format and has proper sourceRoot
  58. try {
  59. const mapContent = JSON.parse(fs.readFileSync(mapPath, "utf8"))
  60. // Ensure the sourceRoot is set correctly for VSCode webview
  61. if (!mapContent.sourceRoot) {
  62. mapContent.sourceRoot = ""
  63. }
  64. // Make sure "sources" paths are relative
  65. if (mapContent.sources) {
  66. mapContent.sources = mapContent.sources.map((source: string) => {
  67. // Remove absolute paths to ensure they work in VSCode webview context
  68. return source.replace(/^\//, "")
  69. })
  70. }
  71. // Write back the updated source map with proper formatting
  72. fs.writeFileSync(mapPath, JSON.stringify(mapContent, null, 2))
  73. console.log(`Updated source map for ${jsFile}`)
  74. } catch (error) {
  75. console.error(`Error processing source map for ${jsFile}:`, error)
  76. }
  77. } else {
  78. console.log(`No source map found for ${jsFile}`)
  79. }
  80. }
  81. // Create a special file to enable source map loading in production
  82. fs.writeFileSync(
  83. path.join(outDir, "sourcemap-manifest.json"),
  84. JSON.stringify({
  85. enabled: true,
  86. version: process.env.PKG_VERSION || "unknown",
  87. buildTime: new Date().toISOString(),
  88. }),
  89. )
  90. console.log("Source map processing complete")
  91. },
  92. },
  93. }
  94. }