Compare commits

...

4 Commits

Author SHA1 Message Date
ephraimduncan bd3192d8f9 Merge branch 'main' into fix/dev-hmr-full-reload
# Conflicts:
#	apps/remix/vite.config.ts
2026-05-08 06:24:27 +00:00
Ephraim Duncan c915ca97ea Merge branch 'main' into fix/dev-hmr-full-reload 2026-05-07 12:40:28 +00:00
ephraimduncan 478bfe3383 Merge branch 'main' into fix/dev-hmr-full-reload
# Conflicts:
#	apps/remix/vite.config.ts
2026-04-30 15:32:43 +00:00
ephraimduncan 6f95494ad9 fix(remix): restrict hono dev-server full-reload to backend files
@hono/vite-dev-server's default handleHotUpdate triggers a full page
reload for any changed module that was loaded for SSR. With React
Router's `ssr: true`, that is essentially every app/route file, so
every edit forced a full reload and React Refresh never ran.

Wrap serverAdapter(...) and override the returned plugin's
handleHotUpdate to only invoke the full-reload path for files under
apps/remix/server/** (the actual Hono backend). Everything else falls
through to the React Router HMR / React Refresh pipeline.
2026-04-30 15:28:09 +00:00
2 changed files with 32 additions and 31 deletions
+32 -17
View File
@@ -16,6 +16,37 @@ const require = createRequire(import.meta.url);
const pdfjsDistPath = path.dirname(require.resolve('pdfjs-dist/package.json'));
const cMapsDir = normalizePath(path.join(pdfjsDistPath, 'cmaps'));
const honoDevServer = serverAdapter({
entry: 'server/router.ts',
getLoadContext: async () => {
const { getLoadContext } = await import('./server/load-context');
return getLoadContext();
},
exclude: [
// Spread the defaults but replace the /.css$/ rule so that Bull
// Board's static CSS at /api/jobs/board/static/** passes through to Hono.
...devServerDefaults.exclude.map((pattern) =>
pattern instanceof RegExp && pattern.source === '.*\\.css$' ? /^(?!\/api\/jobs\/board\/).*\.css$/ : pattern,
),
'/assets/**',
'/src/app/**',
/\?(?:inline|url|no-inline|raw|import(?:&(?:inline|url|no-inline|raw)?)?)$/,
],
});
// Restrict @hono/vite-dev-server's full-reload to backend files. Otherwise it
// fires on any SSR-loaded module change, which kills HMR for the entire app.
const honoServerDir = path.resolve(__dirname, 'server') + path.sep;
const upstreamHandleHotUpdate = honoDevServer.handleHotUpdate;
honoDevServer.handleHotUpdate = async function (ctx) {
if (!ctx.file.startsWith(honoServerDir)) {
return;
}
return typeof upstreamHandleHotUpdate === 'function'
? upstreamHandleHotUpdate.call(this, ctx)
: upstreamHandleHotUpdate?.handler.call(this, ctx);
};
/**
* Note: We load the env variables externally so we can have runtime enviroment variables
* for docker.
@@ -45,23 +76,7 @@ export default defineConfig({
macrosPlugin(),
lingui(),
tsconfigPaths(),
serverAdapter({
entry: 'server/router.ts',
getLoadContext: async () => {
const { getLoadContext } = await import('./server/load-context');
return getLoadContext();
},
exclude: [
// Spread the defaults but replace the /.css$/ rule so that Bull
// Board's static CSS at /api/jobs/board/static/** passes through to Hono.
...devServerDefaults.exclude.map((pattern) =>
pattern instanceof RegExp && pattern.source === '.*\\.css$' ? /^(?!\/api\/jobs\/board\/).*\.css$/ : pattern,
),
'/assets/**',
'/src/app/**',
/\?(?:inline|url|no-inline|raw|import(?:&(?:inline|url|no-inline|raw)?)?)$/,
],
}),
honoDevServer,
],
ssr: {
noExternal: ['react-dropzone', 'plausible-tracker'],
-14
View File
@@ -349,20 +349,6 @@
"dev": true,
"license": "MIT"
},
"apps/docs/node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"apps/docs/node_modules/undici-types": {
"version": "7.19.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz",