From 42e7abedbd77fa464250a1a6ac5d0763cd3baace Mon Sep 17 00:00:00 2001 From: Daniel Williams Date: Sat, 10 Oct 2026 11:06:08 +0100 Subject: [PATCH] fix: restore Node 18 support after security dependency updates fastify 5.12 stopped closing idle keep-alive sockets on close() unless a serverFactory is used, relying on Node 19+ server.close() behaviour. On Node 18 the dev server's stop() hung until the keep-alive timeout. Force closing connections restores the pre-5.12 behaviour. @rsdoctor/rspack-plugin 1.6.4 pulls in rslog 2.3.0, which throws on import under Node < 20. The tester app now only imports it when RSDOCTOR is set. --- .changeset/dev-server-node18-close.md | 5 +++++ apps/tester-app/rspack.config.mjs | 7 ++++++- packages/dev-server/src/createServer.ts | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 .changeset/dev-server-node18-close.md diff --git a/.changeset/dev-server-node18-close.md b/.changeset/dev-server-node18-close.md new file mode 100644 index 000000000..1b5b4f2f0 --- /dev/null +++ b/.changeset/dev-server-node18-close.md @@ -0,0 +1,5 @@ +--- +"@callstack/repack-dev-server": patch +--- + +Fix dev server shutdown hanging on Node 18 with fastify 5.12+ by force-closing open connections on stop diff --git a/apps/tester-app/rspack.config.mjs b/apps/tester-app/rspack.config.mjs index 80bd93db2..641ffbb37 100644 --- a/apps/tester-app/rspack.config.mjs +++ b/apps/tester-app/rspack.config.mjs @@ -2,7 +2,12 @@ import path from 'node:path'; import * as Repack from '@callstack/repack'; import { NativeWindPlugin } from '@callstack/repack-plugin-nativewind'; import { ReanimatedPlugin } from '@callstack/repack-plugin-reanimated'; -import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin'; + +// Rsdoctor (through rslog) throws on import under Node < 20, so only load it +// when it's actually enabled to keep the Node 18 test matrix working. +const { RsdoctorRspackPlugin } = process.env.RSDOCTOR + ? await import('@rsdoctor/rspack-plugin') + : {}; const dirname = Repack.getDirname(import.meta.url); diff --git a/packages/dev-server/src/createServer.ts b/packages/dev-server/src/createServer.ts index 404d956d3..5c1805c91 100644 --- a/packages/dev-server/src/createServer.ts +++ b/packages/dev-server/src/createServer.ts @@ -28,6 +28,10 @@ export async function createServer(config: Server.Config) { /** Fastify instance powering the development server. */ const instance = Fastify({ + // Since fastify 5.12 the default ('idle') leaves idle keep-alive sockets + // to `server.close()`, which only closes them on Node 19+. Force-closing + // keeps `stop()` from hanging on Node 18. + forceCloseConnections: true, disableRequestLogging: options.disableRequestLogging, logger: { level: 'trace',