diff --git a/.changeset/rozenite-port-in-use.md b/.changeset/rozenite-port-in-use.md new file mode 100644 index 0000000..e6beaf3 --- /dev/null +++ b/.changeset/rozenite-port-in-use.md @@ -0,0 +1,5 @@ +--- +"react-native-bundle-discovery-rozenite-plugin": patch +--- + +Don't crash Metro when port 8071 is already in use. With two Metro servers running at once (for example one per git worktree), the second one used to exit on start with `EADDRINUSE`. It now prints a warning and keeps running without its own panel server. diff --git a/packages/rozenite-plugin/src/modules.d.ts b/packages/rozenite-plugin/src/modules.d.ts index d6b69c4..da4b167 100644 --- a/packages/rozenite-plugin/src/modules.d.ts +++ b/packages/rozenite-plugin/src/modules.d.ts @@ -1,6 +1,6 @@ declare module "@discoveryjs/cli" { interface DiscoveryServer { - listen(port: number, callback?: () => void): void; + listen(port: number, callback?: () => void): import("node:http").Server; } export function createServer( options: Record, diff --git a/packages/rozenite-plugin/src/react-native.ts b/packages/rozenite-plugin/src/react-native.ts index d2a25c2..9bdc4a3 100644 --- a/packages/rozenite-plugin/src/react-native.ts +++ b/packages/rozenite-plugin/src/react-native.ts @@ -31,6 +31,8 @@ try { let outputJsonPath = defaultOutputJsonPath; +const SERVER_PORT = 8071; // Also hard-coded in public/index.html + function injectBundleDiscovery( config: T, options?: BundleDiscoveryPluginOptions, @@ -72,7 +74,24 @@ function runServer(): void { dev: false, config: configFile, configFile, - }).then((server) => server.listen(8071)); + }) + .then((server) => { + // Several Metro servers can run at once (for example one per git worktree), but the panel + // server always uses the same port. Without this handler, the second Metro crashes on start + // with EADDRINUSE. Now it keeps running without its own panel server. + server.listen(SERVER_PORT).on("error", (error: NodeJS.ErrnoException) => { + console.warn( + error.code === "EADDRINUSE" + ? `[react-native-bundle-discovery] Port ${SERVER_PORT} is already in use, probably by another Metro. The Bundle Discovery panel will show that server's bundle, not this one.` + : `[react-native-bundle-discovery] Could not start the panel server on port ${SERVER_PORT}: ${error.message}`, + ); + }); + }) + .catch((error: unknown) => { + console.warn( + `[react-native-bundle-discovery] Could not start the panel server: ${String(error)}`, + ); + }); } let isServerRunning = false;