diff --git a/.changeset/mean-clocks-bow.md b/.changeset/mean-clocks-bow.md index f24a9e6c0b3..1a6e66bceb4 100644 --- a/.changeset/mean-clocks-bow.md +++ b/.changeset/mean-clocks-bow.md @@ -37,18 +37,49 @@ Alternatively, you can roll your own with `chokidar` (or similar) if you want to ## Configure -- Dev server port - - flag: `--port` - - future config: `unstable_dev.port` - - default: finds an empty port to use -- App server port - - flag: `--app-server-port` - - future config: `unstable_dev.appServerPort` - - default: `3000` -- Remix request handler path - - Most Remix apps shouldn't need this, but if you wire up the Remix request handler at a specific URL path set this to that path so that the dev server can reliably check your app server for "readiness" - - future flag: `unstable_dev.remixRequestHandlerPath` - - default: `''` -- Rebuild poll interval (milliseconds) - - future config: `unstable_dev.rebuildPollIntervalMs` - - default: 50ms +To enable the new dev server with all defaults, set the `unstable_dev` future flag to `true`: + +```js +// remix.config.js + +module.exports = { + future: { + unstable_dev: true + } +} +``` + +You can also set specific options: + +```js +// remix.config.js + +module.exports = { + future: { + unstable_dev: { + // Port to use for the dev server (i.e. the live reload websocket) + // Can be overridden by a CLI flag: `remix dev --port 3011` + // default: finds an empty port and uses that + port: 3010, + + // Port for your running Remix app server + // Can be overridden by a CLI flag: `remix dev --app-server-port 3021` + // default: `3000` + appServerPort: 3020, + + // Path to the Remix request handler in your app server + // Most app server will route all requests to the Remix request handler and will not need to set this option. + // If your app server _does_ route only certain request paths to the Remix request handler, then you'll need to set this. + // default: `""` + remixRequestHandlerPath: "/products", + + // Milliseconds between "readiness" pings to your app server + // When a Remix rebuild finishes, the dev server will ping a special endpoint (`__REMIX_ASSETS_MANIFEST`) + // to check if your app server is serving up-to-date routes and assets. + // You can set this option to tune how frequently the dev server polls your app server. + // default: `50` + rebuildPollIntervalMs: 25, + } + } +} +``` diff --git a/packages/remix-dev/config.ts b/packages/remix-dev/config.ts index e21d1656d91..c41db0e614e 100644 --- a/packages/remix-dev/config.ts +++ b/packages/remix-dev/config.ts @@ -42,7 +42,7 @@ type Dev = { interface FutureConfig { unstable_cssModules: boolean; unstable_cssSideEffectImports: boolean; - unstable_dev: false | Dev; + unstable_dev: boolean | Dev; unstable_vanillaExtract: boolean; v2_errorBoundary: boolean; v2_meta: boolean; diff --git a/packages/remix-dev/devServer2.ts b/packages/remix-dev/devServer2.ts index eefb475aee9..3ec2f7f1364 100644 --- a/packages/remix-dev/devServer2.ts +++ b/packages/remix-dev/devServer2.ts @@ -45,36 +45,61 @@ let fetchAssetsManifest = async ( } }; +let resolveDev = ( + dev: RemixConfig["future"]["unstable_dev"], + flags: { port?: number; appServerPort?: number } +) => { + if (dev === false) + throw Error("The new dev server requires 'unstable_dev' to be set"); + + let port = flags.port ?? (dev === true ? undefined : dev.port); + let appServerPort = + flags.appServerPort ?? (dev === true || dev.appServerPort == undefined) + ? 3000 + : dev.appServerPort; + let remixRequestHandlerPath = + dev === true || dev.remixRequestHandlerPath === undefined + ? "" + : dev.remixRequestHandlerPath; + let rebuildPollIntervalMs = + dev === true || dev.rebuildPollIntervalMs === undefined + ? 50 + : dev.rebuildPollIntervalMs; + + return { + port, + appServerPort, + remixRequestHandlerPath, + rebuildPollIntervalMs, + }; +}; + export let serve = async ( config: RemixConfig, flags: { port?: number; appServerPort?: number } = {} ) => { await loadEnv(config.rootDirectory); - let { unstable_dev } = config.future; - if (unstable_dev === false) - throw Error("The new dev server requires 'unstable_dev' to be set"); - let { remixRequestHandlerPath, rebuildPollIntervalMs } = unstable_dev; - let appServerPort = flags.appServerPort ?? unstable_dev.appServerPort ?? 3000; + let dev = resolveDev(config.future.unstable_dev, flags); let host = getHost(); - let appServerOrigin = `http://${host ?? "localhost"}:${appServerPort}`; + let appServerOrigin = `http://${host ?? "localhost"}:${dev.appServerPort}`; let waitForAppServer = async (buildHash: string) => { while (true) { // TODO AbortController signal to cancel responses? let assetsManifest = await fetchAssetsManifest( appServerOrigin, - remixRequestHandlerPath ?? "" + dev.remixRequestHandlerPath ); if (assetsManifest?.version === buildHash) return; - await sleep(rebuildPollIntervalMs ?? 50); + await sleep(dev.rebuildPollIntervalMs); } }; // watch and live reload on rebuilds - let port = await findPort(flags.port ?? unstable_dev.port); + let port = await findPort(dev.port); let socket = LiveReload.serve({ port }); let dispose = await Compiler.watch(config, { mode: "development",