Skip to content

Commit

Permalink
feat(dev): easy opt-in to all dev server defaults with true
Browse files Browse the repository at this point in the history
  • Loading branch information
pcattori committed Jan 19, 2023
1 parent 54c612e commit 4bfbe2e
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 25 deletions.
61 changes: 46 additions & 15 deletions .changeset/mean-clocks-bow.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
}
```
2 changes: 1 addition & 1 deletion packages/remix-dev/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
43 changes: 34 additions & 9 deletions packages/remix-dev/devServer2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down

0 comments on commit 4bfbe2e

Please sign in to comment.