From 883a389e836b23a7c216db7c691f77109c0a2c1d Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Wed, 24 May 2023 22:57:25 -0400 Subject: [PATCH] feat(dev): reuse dev server port for websocket (#6476) --- .changeset/wicked-pandas-give.md | 23 ++++++ integration/hmr-log-test.ts | 36 ++++----- integration/hmr-test.ts | 39 +++++----- packages/remix-dev/__tests__/cli-test.ts | 7 +- packages/remix-dev/cli/commands.ts | 78 +++++++------------ packages/remix-dev/cli/run.ts | 34 ++------ packages/remix-dev/compiler/options.ts | 3 +- .../remix-dev/compiler/server/compiler.ts | 2 +- .../compiler/server/plugins/entry.ts | 4 +- packages/remix-dev/config.ts | 10 +-- .../remix-dev/devServer_unstable/index.ts | 66 ++++++++-------- .../remix-dev/devServer_unstable/socket.ts | 5 +- .../remix-react/__tests__/components-test.tsx | 6 +- packages/remix-react/browser.tsx | 2 +- packages/remix-react/components.tsx | 8 +- packages/remix-react/entry.ts | 2 +- packages/remix-server-runtime/build.ts | 2 +- .../remix-server-runtime/serverHandoff.ts | 2 +- 18 files changed, 153 insertions(+), 176 deletions(-) create mode 100644 .changeset/wicked-pandas-give.md diff --git a/.changeset/wicked-pandas-give.md b/.changeset/wicked-pandas-give.md new file mode 100644 index 00000000000..0a998218e57 --- /dev/null +++ b/.changeset/wicked-pandas-give.md @@ -0,0 +1,23 @@ +--- +"@remix-run/dev": minor +"@remix-run/react": minor +"@remix-run/server-runtime": minor +--- + +Reuse dev server port for WebSocket (Live Reload,HMR,HDR) + +As a result the `webSocketPort`/`--websocket-port` option has been obsoleted. +Additionally, scheme/host/port options for the dev server have been renamed. + +Available options are: + +| Option | flag | config | default | +| -------------- | ------------------ | ---------------- | --------------------------------- | +| Command | `-c` / `--command` | `command` | `remix-serve ` | +| Scheme | `--scheme` | `scheme` | `http` | +| Host | `--host` | `host` | `localhost` | +| Port | `--port` | `port` | Dynamically chosen open port | +| No restart | `--no-restart` | `restart: false` | `restart: true` | + +Note that scheme/host/port options are for the _dev server_, not your app server. +You probably don't need to use scheme/host/port option if you aren't configuring networking (e.g. for Docker or SSL). diff --git a/integration/hmr-log-test.ts b/integration/hmr-log-test.ts index 1a9fe3af396..54ab8b6c01a 100644 --- a/integration/hmr-log-test.ts +++ b/integration/hmr-log-test.ts @@ -9,11 +9,7 @@ import { createFixtureProject, css, js, json } from "./helpers/create-fixture"; test.setTimeout(120_000); -let fixture = (options: { - appServerPort: number; - httpPort: number; - webSocketPort: number; -}) => ({ +let fixture = (options: { appPort: number; devPort: number }) => ({ files: { "remix.config.js": js` module.exports = { @@ -21,8 +17,7 @@ let fixture = (options: { tailwind: true, future: { unstable_dev: { - httpPort: ${options.httpPort}, - webSocketPort: ${options.webSocketPort}, + port: ${options.devPort}, }, v2_routeConvention: true, v2_errorBoundary: true, @@ -80,7 +75,7 @@ let fixture = (options: { }) ); - let port = ${options.appServerPort}; + let port = ${options.appPort}; app.listen(port, () => { let build = require(BUILD_DIR); console.log('✅ app ready: http://localhost:' + port); @@ -250,12 +245,9 @@ test("HMR", async ({ page }) => { }); let portRange = makeRange(4080, 4099); - let appServerPort = await getPort({ port: portRange }); - let httpPort = await getPort({ port: portRange }); - let webSocketPort = await getPort({ port: portRange }); - let projectDir = await createFixtureProject( - fixture({ appServerPort, httpPort, webSocketPort }) - ); + let appPort = await getPort({ port: portRange }); + let devPort = await getPort({ port: portRange }); + let projectDir = await createFixtureProject(fixture({ appPort, devPort })); // spin up dev server let dev = execa("npm", ["run", "dev"], { cwd: projectDir }); @@ -270,7 +262,7 @@ test("HMR", async ({ page }) => { { timeoutMs: 10_000 } ); - await page.goto(`http://localhost:${appServerPort}`, { + await page.goto(`http://localhost:${appPort}`, { waitUntil: "networkidle", }); @@ -470,7 +462,7 @@ whatsup await page.getByText("Hello, planet").waitFor({ timeout: HMR_TIMEOUT_MS }); await page.waitForLoadState("networkidle"); - expect(devStderr()).toBe(""); + let stderr = devStderr(); let withSyntaxError = ` import { useLoaderData } from "@remix-run/react"; export function shouldRevalidate(args) { @@ -486,9 +478,15 @@ whatsup } `; fs.writeFileSync(indexPath, withSyntaxError); - await wait(() => devStderr().includes('Expected ";" but found "efault"'), { - timeoutMs: HMR_TIMEOUT_MS, - }); + await wait( + () => + devStderr() + .replace(stderr, "") + .includes('Expected ";" but found "efault"'), + { + timeoutMs: HMR_TIMEOUT_MS, + } + ); let withFix = ` import { useLoaderData } from "@remix-run/react"; diff --git a/integration/hmr-test.ts b/integration/hmr-test.ts index 6f6b63fd291..45aa771ec01 100644 --- a/integration/hmr-test.ts +++ b/integration/hmr-test.ts @@ -9,11 +9,7 @@ import { createFixtureProject, css, js, json } from "./helpers/create-fixture"; test.setTimeout(120_000); -let fixture = (options: { - appServerPort: number; - httpPort: number; - webSocketPort: number; -}) => ({ +let fixture = (options: { appPort: number; devPort: number }) => ({ files: { "remix.config.js": js` module.exports = { @@ -21,8 +17,7 @@ let fixture = (options: { tailwind: true, future: { unstable_dev: { - httpPort: ${options.httpPort}, - webSocketPort: ${options.webSocketPort}, + port: ${options.devPort}, }, v2_routeConvention: true, v2_errorBoundary: true, @@ -69,18 +64,17 @@ let fixture = (options: { const app = express(); app.use(express.static("public", { immutable: true, maxAge: "1y" })); - const MODE = process.env.NODE_ENV; const BUILD_DIR = path.join(process.cwd(), "build"); app.all( "*", createRequestHandler({ build: require(BUILD_DIR), - mode: MODE, + mode: process.env.NODE_ENV, }) ); - let port = ${options.appServerPort}; + let port = ${options.appPort}; app.listen(port, () => { let build = require(BUILD_DIR); console.log('✅ app ready: http://localhost:' + port); @@ -249,12 +243,9 @@ test("HMR", async ({ page }) => { }); let portRange = makeRange(3080, 3099); - let appServerPort = await getPort({ port: portRange }); - let httpPort = await getPort({ port: portRange }); - let webSocketPort = await getPort({ port: portRange }); - let projectDir = await createFixtureProject( - fixture({ appServerPort, httpPort, webSocketPort }) - ); + let appPort = await getPort({ port: portRange }); + let devPort = await getPort({ port: portRange }); + let projectDir = await createFixtureProject(fixture({ appPort, devPort })); // spin up dev server let dev = execa("npm", ["run", "dev"], { cwd: projectDir }); @@ -269,7 +260,7 @@ test("HMR", async ({ page }) => { { timeoutMs: 10_000 } ); - await page.goto(`http://localhost:${appServerPort}`, { + await page.goto(`http://localhost:${appPort}`, { waitUntil: "networkidle", }); @@ -469,7 +460,7 @@ whatsup await page.getByText("Hello, planet").waitFor({ timeout: HMR_TIMEOUT_MS }); await page.waitForLoadState("networkidle"); - expect(devStderr()).toBe(""); + let stderr = devStderr(); let withSyntaxError = ` import { useLoaderData } from "@remix-run/react"; export function shouldRevalidate(args) { @@ -485,9 +476,15 @@ whatsup } `; fs.writeFileSync(indexPath, withSyntaxError); - await wait(() => devStderr().includes('Expected ";" but found "efault"'), { - timeoutMs: HMR_TIMEOUT_MS, - }); + await wait( + () => + devStderr() + .replace(stderr, "") + .includes('Expected ";" but found "efault"'), + { + timeoutMs: HMR_TIMEOUT_MS, + } + ); let withFix = ` import { useLoaderData } from "@remix-run/react"; diff --git a/packages/remix-dev/__tests__/cli-test.ts b/packages/remix-dev/__tests__/cli-test.ts index 0ce72093343..5e14cc52a1a 100644 --- a/packages/remix-dev/__tests__/cli-test.ts +++ b/packages/remix-dev/__tests__/cli-test.ts @@ -118,11 +118,10 @@ describe("remix CLI", () => { [unstable_dev] --command, -c Command used to run your app server - --http-scheme HTTP(S) scheme for the dev server. Default: http - --http-host HTTP(S) host for the dev server. Default: localhost - --http-port HTTP(S) port for the dev server. Default: any open port + --scheme Scheme for the dev server. Default: http + --host Host for the dev server. Default: localhost + --port Port for the dev server. Default: any open port --no-restart Do not restart the app server when rebuilds occur. - --websocket-port WebSocket port for the dev server. Default: any open port \`init\` Options: --no-delete Skip deleting the \`remix.init\` script \`routes\` Options: diff --git a/packages/remix-dev/cli/commands.ts b/packages/remix-dev/cli/commands.ts index 2042fcaafa8..314650d0eef 100644 --- a/packages/remix-dev/cli/commands.ts +++ b/packages/remix-dev/cli/commands.ts @@ -178,13 +178,8 @@ export async function build( onWarning: warnOnce, }; if (mode === "development" && config.future.unstable_dev) { - let dev = await resolveDevBuild(config); - options.devHttpOrigin = { - scheme: dev.httpScheme, - host: dev.httpHost, - port: dev.httpPort, - }; - options.devWebSocketPort = dev.webSocketPort; + let origin = await resolveDevOrigin(config); + options.devOrigin = origin; } fse.emptyDirSync(config.assetsBuildDirectory); await compiler.build({ config, options }).catch((thrown) => { @@ -216,21 +211,21 @@ export async function dev( remixRoot: string, flags: { debug?: boolean; - port?: number; // TODO: remove for v2 metafile?: boolean // unstable_dev command?: string; - httpScheme?: string; - httpHost?: string; - httpPort?: number; + scheme?: string; + host?: string; + port?: number; restart?: boolean; - websocketPort?: number; } = {} ) { if (process.env.NODE_ENV && process.env.NODE_ENV !== "development") { console.warn( - `Forcing NODE_ENV to be 'development'. Was: ${process.env.NODE_ENV}` + `Forcing NODE_ENV to be 'development'. Was: ${JSON.stringify( + process.env.NODE_ENV + )}` ); } process.env.NODE_ENV = "development"; @@ -474,49 +469,42 @@ let parseMode = ( let findPort = async () => getPort({ port: makeRange(3001, 3100) }); -type DevBuildFlags = { - httpScheme: string; - httpHost: string; - httpPort: number; - webSocketPort: number; +type DevOrigin = { + scheme: string; + host: string; + port: number; }; -let resolveDevBuild = async ( +let resolveDevOrigin = async ( config: RemixConfig, - flags: Partial = {} -): Promise => { + flags: Partial = {} +): Promise => { let dev = config.future.unstable_dev; if (dev === false) throw Error("This should never happen"); // prettier-ignore - let httpScheme = - flags.httpScheme ?? - (dev === true ? undefined : dev.httpScheme) ?? + let scheme = + flags.scheme ?? + (dev === true ? undefined : dev.scheme) ?? "http"; // prettier-ignore - let httpHost = - flags.httpHost ?? - (dev === true ? undefined : dev.httpHost) ?? + let host = + flags.host ?? + (dev === true ? undefined : dev.host) ?? "localhost"; // prettier-ignore - let httpPort = - flags.httpPort ?? - (dev === true ? undefined : dev.httpPort) ?? - (await findPort()); - // prettier-ignore - let webSocketPort = - flags.webSocketPort ?? - (dev === true ? undefined : dev.webSocketPort) ?? + let port = + flags.port ?? + (dev === true ? undefined : dev.port) ?? (await findPort()); return { - httpScheme, - httpHost, - httpPort, - webSocketPort, + scheme, + host, + port, }; }; -type DevServeFlags = DevBuildFlags & { +type DevServeFlags = DevOrigin & { command: string; restart: boolean; }; @@ -527,10 +515,7 @@ let resolveDevServe = async ( let dev = config.future.unstable_dev; if (dev === false) throw Error("Cannot resolve dev options"); - let { httpScheme, httpHost, httpPort, webSocketPort } = await resolveDevBuild( - config, - flags - ); + let origin = await resolveDevOrigin(config, flags); // prettier-ignore let command = @@ -561,10 +546,7 @@ let resolveDevServe = async ( return { command, - httpScheme, - httpHost, - httpPort, - webSocketPort, + ...origin, restart, }; }; diff --git a/packages/remix-dev/cli/run.ts b/packages/remix-dev/cli/run.ts index a6ba3dcb5d6..51298169ddb 100644 --- a/packages/remix-dev/cli/run.ts +++ b/packages/remix-dev/cli/run.ts @@ -46,11 +46,10 @@ ${colors.logoBlue("R")} ${colors.logoGreen("E")} ${colors.logoYellow( [unstable_dev] --command, -c Command used to run your app server - --http-scheme HTTP(S) scheme for the dev server. Default: http - --http-host HTTP(S) host for the dev server. Default: localhost - --http-port HTTP(S) port for the dev server. Default: any open port + --scheme Scheme for the dev server. Default: http + --host Host for the dev server. Default: localhost + --port Port for the dev server. Default: any open port --no-restart Do not restart the app server when rebuilds occur. - --websocket-port WebSocket port for the dev server. Default: any open port \`init\` Options: --no-delete Skip deleting the \`remix.init\` script \`routes\` Options: @@ -172,8 +171,6 @@ export async function run(argv: string[] = process.argv.slice(2)) { "--interactive": Boolean, "--no-interactive": Boolean, "--json": Boolean, - "--port": Number, - "-p": "--port", "--remix-version": String, "--sourcemap": Boolean, "--metafile": Boolean, @@ -187,11 +184,11 @@ export async function run(argv: string[] = process.argv.slice(2)) { // dev server "--command": String, "-c": "--command", - "--http-scheme": String, - "--http-host": String, - "--http-port": Number, + "--scheme": String, + "--host": String, + "--port": Number, + "-p": "--port", "--no-restart": Boolean, - "--websocket-port": Number, }, { argv, @@ -216,23 +213,6 @@ export async function run(argv: string[] = process.argv.slice(2)) { return; } - if (flags["http-scheme"]) { - flags.httpScheme = flags["http-scheme"]; - delete flags["http-scheme"]; - } - if (flags["http-host"]) { - flags.httpHost = flags["http-host"]; - delete flags["http-host"]; - } - if (flags["http-port"]) { - flags.httpPort = flags["http-port"]; - delete flags["http-port"]; - } - if (flags["websocket-port"]) { - flags.webSocketPort = flags["websocket-port"]; - delete flags["websocket-port"]; - } - if (args["--no-delete"]) { flags.delete = false; } diff --git a/packages/remix-dev/compiler/options.ts b/packages/remix-dev/compiler/options.ts index 34f6dade720..6d9b8c170b9 100644 --- a/packages/remix-dev/compiler/options.ts +++ b/packages/remix-dev/compiler/options.ts @@ -7,10 +7,9 @@ export type Options = { onWarning?: (message: string, key: string) => void; // TODO: required in v2 - devHttpOrigin?: { + devOrigin?: { scheme: string; host: string; port: number; }; - devWebSocketPort?: number; }; diff --git a/packages/remix-dev/compiler/server/compiler.ts b/packages/remix-dev/compiler/server/compiler.ts index 3dd99e80ffe..47af4230248 100644 --- a/packages/remix-dev/compiler/server/compiler.ts +++ b/packages/remix-dev/compiler/server/compiler.ts @@ -103,7 +103,7 @@ const createEsbuildConfig = ( ctx.config.devServerPort ), "process.env.REMIX_DEV_HTTP_ORIGIN": JSON.stringify( - ctx.options.devHttpOrigin ?? "" // TODO: remove nullish check in v2 + ctx.options.devOrigin ?? "" // TODO: remove nullish check in v2 ), }, jsx: "automatic", diff --git a/packages/remix-dev/compiler/server/plugins/entry.ts b/packages/remix-dev/compiler/server/plugins/entry.ts index 3d64193e3b4..4966dd3ad93 100644 --- a/packages/remix-dev/compiler/server/plugins/entry.ts +++ b/packages/remix-dev/compiler/server/plugins/entry.ts @@ -51,9 +51,9 @@ ${Object.keys(config.routes) export const publicPath = ${JSON.stringify(config.publicPath)}; export const entry = { module: entryServer }; ${ - options.devWebSocketPort + options.devOrigin ? `export const dev = ${JSON.stringify({ - websocketPort: options.devWebSocketPort, + port: options.devOrigin.port, })}` : "" } diff --git a/packages/remix-dev/config.ts b/packages/remix-dev/config.ts index c482614a337..0f38e8ed9d4 100644 --- a/packages/remix-dev/config.ts +++ b/packages/remix-dev/config.ts @@ -37,15 +37,11 @@ export type ServerModuleFormat = "esm" | "cjs"; export type ServerPlatform = "node" | "neutral"; type Dev = { - port?: number; // TODO: remove in v2 - command?: string; - httpScheme?: string; - httpHost?: string; - httpPort?: number; - webSocketPort?: number; + scheme?: string; + host?: string; + port?: number; restart?: boolean; - publicDirectory?: string; }; interface FutureConfig { diff --git a/packages/remix-dev/devServer_unstable/index.ts b/packages/remix-dev/devServer_unstable/index.ts index 412be340334..5272073b007 100644 --- a/packages/remix-dev/devServer_unstable/index.ts +++ b/packages/remix-dev/devServer_unstable/index.ts @@ -1,5 +1,6 @@ import * as path from "node:path"; import * as stream from "node:stream"; +import * as http from "node:http"; import fs from "fs-extra"; import prettyMs from "pretty-ms"; import execa from "execa"; @@ -41,21 +42,13 @@ export let serve = async ( initialConfig: RemixConfig, options: { command: string; - httpScheme: string; - httpHost: string; - httpPort: number; - webSocketPort: number; + scheme: string; + host: string; + port: number; restart: boolean; } ) => { await loadEnv(initialConfig.rootDirectory); - let websocket = Socket.serve({ port: options.webSocketPort }); - let httpOrigin: Origin = { - scheme: options.httpScheme, - host: options.httpHost, - port: options.httpPort, - }; - let state: { appServer?: execa.ExecaChildProcess; manifest?: Manifest; @@ -65,6 +58,30 @@ export let serve = async ( prevLoaderHashes?: Record; } = {}; + let app = express() + // handle `broadcastDevReady` messages + .use(express.json()) + .post("/ping", (req, res) => { + let { buildHash } = req.body; + if (typeof buildHash !== "string") { + console.warn(`Unrecognized payload: ${req.body}`); + res.sendStatus(400); + } + if (buildHash === state.manifest?.version) { + state.appReady?.ok(); + } + res.sendStatus(200); + }); + + let server = http.createServer(app); + let websocket = Socket.serve(server); + + let origin: Origin = { + scheme: options.scheme, + host: options.host, + port: options.port, + }; + let bin = await detectBin(); let startAppServer = (command: string) => { console.log(`> ${command}`); @@ -74,7 +91,7 @@ export let serve = async ( NODE_ENV: "development", PATH: bin + (process.platform === "win32" ? ";" : ":") + process.env.PATH, - REMIX_DEV_HTTP_ORIGIN: stringifyOrigin(httpOrigin), + REMIX_DEV_HTTP_ORIGIN: stringifyOrigin(origin), }, // https://github.com/sindresorhus/execa/issues/433 windowsHide: false, @@ -119,8 +136,7 @@ export let serve = async ( sourcemap: true, metafile: initialConfig.metafile, onWarning: warnOnce, - devHttpOrigin: httpOrigin, - devWebSocketPort: options.webSocketPort, + devOrigin: origin, }, }, { @@ -199,28 +215,14 @@ export let serve = async ( } ); - let httpServer = express() - // handle `broadcastDevReady` messages - .use(express.json()) - .post("/ping", (req, res) => { - let { buildHash } = req.body; - if (typeof buildHash !== "string") { - console.warn(`Unrecognized payload: ${req.body}`); - res.sendStatus(400); - } - if (buildHash === state.manifest?.version) { - state.appReady?.ok(); - } - res.sendStatus(200); - }) - .listen(httpOrigin.port, () => { - console.log("Remix dev server ready"); - }); + server.listen(origin.port, () => { + console.log("Remix dev server ready"); + }); return new Promise(() => { }).finally(async () => { await kill(state.appServer); websocket.close(); - httpServer.close(); + server.close(); await dispose(); }); }; diff --git a/packages/remix-dev/devServer_unstable/socket.ts b/packages/remix-dev/devServer_unstable/socket.ts index 83ea95fb5ca..a66ca95a0db 100644 --- a/packages/remix-dev/devServer_unstable/socket.ts +++ b/packages/remix-dev/devServer_unstable/socket.ts @@ -1,4 +1,5 @@ import WebSocket from "ws"; +import type { Server as HTTPServer } from "http"; import { type Manifest } from "../manifest"; import type * as HMR from "./hmr"; @@ -14,8 +15,8 @@ type Message = type Broadcast = (message: Message) => void; -export let serve = (options: { port: number }) => { - let wss = new WebSocket.Server({ port: options.port }); +export let serve = (server: HTTPServer) => { + let wss = new WebSocket.Server({ server }); let broadcast: Broadcast = (message) => { wss.clients.forEach((client) => { diff --git a/packages/remix-react/__tests__/components-test.tsx b/packages/remix-react/__tests__/components-test.tsx index b088805a445..6cb621925b1 100644 --- a/packages/remix-react/__tests__/components-test.tsx +++ b/packages/remix-react/__tests__/components-test.tsx @@ -47,14 +47,14 @@ describe("", () => { LiveReload = require("../components").LiveReload; let { container } = render(); expect(container.querySelector("script")).toHaveTextContent( - "let port = (window.__remixContext && window.__remixContext.dev && window.__remixContext.dev.websocketPort) || 8002;" + "let port = undefined || (window.__remixContext && window.__remixContext.dev && window.__remixContext.dev.port) || 8002;" ); }); it("can set the port explicitly", () => { let { container } = render(); expect(container.querySelector("script")).toHaveTextContent( - "let port = (window.__remixContext && window.__remixContext.dev && window.__remixContext.dev.websocketPort) || 4321;" + "let port = 4321 || (window.__remixContext && window.__remixContext.dev && window.__remixContext.dev.port) || 8002;" ); }); @@ -62,7 +62,7 @@ describe("", () => { process.env.REMIX_DEV_SERVER_WS_PORT = "1234"; let { container } = render(); expect(container.querySelector("script")).toHaveTextContent( - "let port = (window.__remixContext && window.__remixContext.dev && window.__remixContext.dev.websocketPort) || 1234;" + "let port = undefined || (window.__remixContext && window.__remixContext.dev && window.__remixContext.dev.port) || 1234;" ); }); diff --git a/packages/remix-react/browser.tsx b/packages/remix-react/browser.tsx index c81a6ed80fc..821731a3dad 100644 --- a/packages/remix-react/browser.tsx +++ b/packages/remix-react/browser.tsx @@ -24,7 +24,7 @@ declare global { // The number of active deferred keys rendered on the server a?: number; dev?: { - websocketPort?: number; + port?: number; hmrRuntime?: string; }; }; diff --git a/packages/remix-react/components.tsx b/packages/remix-react/components.tsx index cd5fbf8e8a9..661447f5c53 100644 --- a/packages/remix-react/components.tsx +++ b/packages/remix-react/components.tsx @@ -1714,7 +1714,7 @@ export const LiveReload = ? () => null : function LiveReload({ // TODO: remove REMIX_DEV_SERVER_WS_PORT in v2 - port = Number(process.env.REMIX_DEV_SERVER_WS_PORT || 8002), + port, timeoutMs = 1000, nonce = undefined, }: { @@ -1732,9 +1732,9 @@ export const LiveReload = function remixLiveReloadConnect(config) { let protocol = location.protocol === "https:" ? "wss:" : "ws:"; let host = location.hostname; - let port = (window.__remixContext && window.__remixContext.dev && window.__remixContext.dev.websocketPort) || ${String( - port - )}; + let port = ${port} || (window.__remixContext && window.__remixContext.dev && window.__remixContext.dev.port) || ${Number( + process.env.REMIX_DEV_SERVER_WS_PORT || 8002 + )}; let socketPath = protocol + "//" + host + ":" + port + "/socket"; let ws = new WebSocket(socketPath); ws.onmessage = async (message) => { diff --git a/packages/remix-react/entry.ts b/packages/remix-react/entry.ts index d2a2ab2f269..cfef8123a4d 100644 --- a/packages/remix-react/entry.ts +++ b/packages/remix-react/entry.ts @@ -10,7 +10,7 @@ export interface RemixContextObject { serverHandoffString?: string; future: FutureConfig; abortDelay?: number; - dev?: { websocketPort: number }; + dev?: { port: number }; } // Additional React-Router information needed at runtime, but not hydrated diff --git a/packages/remix-server-runtime/build.ts b/packages/remix-server-runtime/build.ts index 4e1b831b1f2..dfa5e281054 100644 --- a/packages/remix-server-runtime/build.ts +++ b/packages/remix-server-runtime/build.ts @@ -15,7 +15,7 @@ export interface ServerBuild { publicPath: string; assetsBuildDirectory: string; future: FutureConfig; - dev?: { websocketPort: number }; + dev?: { port: number }; } export interface HandleDocumentRequestFunction { diff --git a/packages/remix-server-runtime/serverHandoff.ts b/packages/remix-server-runtime/serverHandoff.ts index edc4d4b3055..0ea04f24493 100644 --- a/packages/remix-server-runtime/serverHandoff.ts +++ b/packages/remix-server-runtime/serverHandoff.ts @@ -20,7 +20,7 @@ export function createServerHandoffString(serverHandoff: { // we'd end up including duplicate info state: ValidateShape; future: FutureConfig; - dev?: { websocketPort: number }; + dev?: { port: number }; }): string { // Uses faster alternative of jsesc to escape data returned from the loaders. // This string is inserted directly into the HTML in the `` element.