From 0a3ba7153024aa1012b640986d4d5eea6f3bae68 Mon Sep 17 00:00:00 2001 From: Eric Wheeler Date: Sat, 5 Apr 2025 19:52:01 -0700 Subject: [PATCH] dev: dynamic Vite port detection for webview development Implements a solution for the Vite port collision issue that allows easier development of Roo across multiple instances of VSCode in different Roo repository directories. This may also fix crashes and strange behavior between multiple running instances that would otherwise create port conflicts. This is solved using the following automated process: - When Vite automatically selects an alternative port, a custom plugin automatically writes the port to a '.vite-port' file in the repository root - ClineProvider automatically reads the port from this file, falling back gracefully to port 5173 if the file doesn't exist - No user intervention is necessary as the entire process is handled automatically - Added detailed logging for debugging - Added .vite-port to .gitignore The extension now connects to the correct Vite development server port automatically, even when the default port (5173) is already in use. Signed-off-by: Eric Wheeler --- .gitignore | 3 +++ src/core/webview/ClineProvider.ts | 21 ++++++++++++++++++++- webview-ui/vite.config.ts | 27 ++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index cc6551885f2..12777329698 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ docs/_site/ #Logging logs + +# Vite development +.vite-port diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 9824e305fac..0d3f21478a9 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -579,7 +579,26 @@ export class ClineProvider extends EventEmitter implements } private async getHMRHtmlContent(webview: vscode.Webview): Promise { - const localPort = "5173" + // Try to read the port from the file + let localPort = "5173" // Default fallback + try { + const fs = require("fs") + const path = require("path") + const portFilePath = path.resolve(__dirname, "../.vite-port") + + if (fs.existsSync(portFilePath)) { + localPort = fs.readFileSync(portFilePath, "utf8").trim() + console.log(`[ClineProvider:Vite] Using Vite server port from ${portFilePath}: ${localPort}`) + } else { + console.log( + `[ClineProvider:Vite] Port file not found at ${portFilePath}, using default port: ${localPort}`, + ) + } + } catch (err) { + console.error("[ClineProvider:Vite] Failed to read Vite port file:", err) + // Continue with default port if file reading fails + } + const localServerUrl = `localhost:${localPort}` // Check if local dev server is running. diff --git a/webview-ui/vite.config.ts b/webview-ui/vite.config.ts index b1fdc1f3cbd..243bb658ec4 100644 --- a/webview-ui/vite.config.ts +++ b/webview-ui/vite.config.ts @@ -1,12 +1,37 @@ import path from "path" +import fs from "fs" import { defineConfig } from "vite" import react from "@vitejs/plugin-react" import tailwindcss from "@tailwindcss/vite" +// Custom plugin to write the server port to a file +const writePortToFile = () => { + return { + name: "write-port-to-file", + configureServer(server) { + // Write the port to a file when the server starts + server.httpServer?.once("listening", () => { + const address = server.httpServer.address() + const port = typeof address === "object" && address ? address.port : null + + if (port) { + // Write to a file in the project root + const portFilePath = path.resolve(__dirname, "../.vite-port") + fs.writeFileSync(portFilePath, port.toString()) + console.log(`[Vite Plugin] Server started on port ${port}`) + console.log(`[Vite Plugin] Port information written to ${portFilePath}`) + } else { + console.warn("[Vite Plugin] Could not determine server port") + } + }) + }, + } +} + // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react(), tailwindcss()], + plugins: [react(), tailwindcss(), writePortToFile()], resolve: { alias: { "@": path.resolve(__dirname, "./src"),