Skip to content

Commit 9703630

Browse files
authored
[Fix] Prevent build import conflicts by splitting imports into chunks (#149)
* Rollback single file server output (revert to 2.16.0 behavior) * Prevent build import conflicts by splitting imports into chunks
1 parent 60d5ba6 commit 9703630

File tree

8 files changed

+46
-41
lines changed

8 files changed

+46
-41
lines changed

.changeset/curly-loops-enjoy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"react-router-hono-server": minor
3+
---
4+
5+
Prevent build import conflicts by splitting imports into chunks

.changeset/great-items-attack.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"react-router-hono-server": minor
3+
---
4+
5+
Rollback single file server output (revert to 2.16.0 behavior)

.github/workflows/publish-commit.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: 🚀 pkg-pr-new
2-
on: [push, pull_request]
2+
on: [pull_request]
33

44
jobs:
55
build:

README.md

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ touch app/server.ts
305305
// app/server.ts
306306
import { createHonoServer } from "react-router-hono-server/node";
307307

308-
export default await createHonoServer({/* options */});
308+
export default createHonoServer({/* options */});
309309
```
310310

311311
#### Alternative
@@ -325,7 +325,7 @@ It is useful if you have many middleware and want to keep your server file clean
325325
326326
import { createHonoServer } from "react-router-hono-server/node";
327327
328-
export default await createHonoServer({/* options */});
328+
export default createHonoServer({/* options */});
329329
```
330330
331331
#### I don't like this default
@@ -526,12 +526,6 @@ export type HonoServerOptions<E extends Env = BlankEnv> = {
526526
527527
You can add additional Hono middleware with the `configure` function. If you do not provide a function, it will create a default Hono server.
528528
529-
The `configure` function can be async. So, make sure to `await createHonoServer()`.
530-
531-
> NB: If you import some shared code in your server file (or middleware), Vite will code split the file (your server code will be in a separate chunk, re-exported as default in `build/server/index.js`).
532-
>
533-
> In this situation, if you `await createHonoServer()` it will error with `Detected unsettled top-level await`. Just remove the `await` and it will work fine.
534-
535529
If you want to set up the React Router `AppLoadContext`, pass in a function to `getLoadContext`.
536530
537531
Modify the `AppLoadContext` interface used in your app.
@@ -557,7 +551,7 @@ declare module "react-router" {
557551
}
558552
}
559553
560-
export default await createHonoServer({
554+
export default createHonoServer({
561555
getLoadContext(_, { build, mode }) {
562556
const isProductionMode = mode === "production";
563557
return {
@@ -743,7 +737,7 @@ You can use it to add protection middleware, for example.
743737
import { reactRouterRedirect } from "react-router-hono-server/http";
744738
import { createHonoServer } from "react-router-hono-server/node";
745739
746-
export default await createHonoServer({
740+
export default createHonoServer({
747741
beforeAll(app) {
748742
app.use(async (c, next) => {
749743
if (c.req.path.includes("/protected") && !c.req.header("Authorization")) {
@@ -765,7 +759,7 @@ import { createCookieSessionStorage } from "react-router";
765759
import { createHonoServer } from "react-router-hono-server/node";
766760
import { session } from "remix-hono/session";
767761
768-
export default await createHonoServer({
762+
export default createHonoServer({
769763
configure: (server) => {
770764
server.use(
771765
session({
@@ -808,7 +802,7 @@ Then, use them with the `configure` function of `createHonoServer`.
808802
import { createMiddleware } from "hono/factory";
809803
import { createHonoServer } from "react-router-hono-server/node";
810804
811-
export default await createHonoServer({
805+
export default createHonoServer({
812806
configure: (server) => {
813807
server.use(
814808
createMiddleware(async (c, next) => {
@@ -846,7 +840,7 @@ import { createHonoServer } from "react-router-hono-server/node";
846840
// Store connected clients
847841
const clients = new Set<WSContext>();
848842
849-
export default await createHonoServer({
843+
export default createHonoServer({
850844
useWebSocket: true,
851845
// 👆 Unlock this 👇 from @hono/node-ws
852846
configure: (app, { upgradeWebSocket }) => {
@@ -892,7 +886,7 @@ import { createHonoServer } from "react-router-hono-server/bun";
892886
// Store connected clients
893887
const clients = new Set<WSContext>();
894888
895-
export default await createHonoServer({
889+
export default createHonoServer({
896890
useWebSocket: true,
897891
// 👆 Unlock this 👇 from @hono/node-ws in dev, hono/bun in prod
898892
configure(app, { upgradeWebSocket }) {
@@ -976,7 +970,7 @@ const app = new Hono();
976970
// Mount the API app at /api
977971
app.route(API_BASENAME, api);
978972
979-
export default await createHonoServer({
973+
export default createHonoServer({
980974
// Pass the root Hono app to the server.
981975
// It will be used to mount the React Router app on the `basename` defined in react-router.config.ts
982976
app,
@@ -1070,7 +1064,7 @@ We now use the Vite virtual import `virtual:react-router/server-build` to load t
10701064
> ```ts
10711065
> import { createHonoServer } from "react-router-hono-server/node";
10721066
>
1073-
> export default await createHonoServer({/* other options */});
1067+
> export default createHonoServer({/* other options */});
10741068
> ```
10751069
10761070
### Update your `vite.config.ts`

package.json

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,7 @@
8686
"bin": {
8787
"react-router-hono-server": "dist/cli.js"
8888
},
89-
"files": [
90-
"dist"
91-
],
89+
"files": ["dist"],
9290
"homepage": "https://github.com/rphlmr/react-router-hono-server#readme",
9391
"dependencies": {
9492
"@drizzle-team/brocli": "^0.11.0",
@@ -139,12 +137,6 @@
139137
},
140138
"packageManager": "[email protected]",
141139
"pnpm": {
142-
"onlyBuiltDependencies": [
143-
"@biomejs/biome",
144-
"esbuild",
145-
"lefthook",
146-
"sharp",
147-
"workerd"
148-
]
140+
"onlyBuiltDependencies": ["@biomejs/biome", "esbuild", "lefthook", "sharp", "workerd"]
149141
}
150142
}

src/adapters/bun.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// @ts-expect-error - Virtual module provided by React Router at build time
2-
import * as build from "virtual:react-router/server-build";
3-
41
import type { Serve, ServeOptions } from "bun";
52
import { type Env, Hono } from "hono";
63
import { serveStatic } from "hono/bun";
@@ -15,6 +12,7 @@ import {
1512
createGetLoadContext,
1613
createWebSocket,
1714
getBuildMode,
15+
importBuild,
1816
patchUpgradeListener,
1917
} from "../helpers";
2018
import { cache } from "../middleware";
@@ -71,6 +69,7 @@ export async function createHonoServer<E extends Env = BlankEnv>(
7169
options?: HonoServerOptionsWithWebSocket<E>
7270
): Promise<CustomBunServer>;
7371
export async function createHonoServer<E extends Env = BlankEnv>(options?: HonoServerOptions<E>) {
72+
const build = await importBuild();
7473
const basename = import.meta.env.REACT_ROUTER_HONO_SERVER_BASENAME;
7574
const mergedOptions: HonoServerOptions<E> = {
7675
...options,

src/adapters/node.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// @ts-expect-error - Virtual module provided by React Router at build time
2-
import * as build from "virtual:react-router/server-build";
3-
41
import type { AddressInfo } from "node:net";
52
import { type ServerType, serve } from "@hono/node-server";
63
import { type ServeStaticOptions, serveStatic } from "@hono/node-server/serve-static";
@@ -15,6 +12,7 @@ import {
1512
createGetLoadContext,
1613
createWebSocket,
1714
getBuildMode,
15+
importBuild,
1816
patchUpgradeListener,
1917
} from "../helpers";
2018
import { cache } from "../middleware";
@@ -95,6 +93,8 @@ export async function createHonoServer<E extends Env = BlankEnv>(
9593
options?: HonoServerOptionsWithWebSocket<E>
9694
): Promise<Hono<E>>;
9795
export async function createHonoServer<E extends Env = BlankEnv>(options?: HonoServerOptions<E>) {
96+
const startTime = Date.now();
97+
const build = await importBuild();
9898
const basename = import.meta.env.REACT_ROUTER_HONO_SERVER_BASENAME;
9999
const mergedOptions: HonoServerOptions<E> = {
100100
...options,
@@ -107,6 +107,8 @@ export async function createHonoServer<E extends Env = BlankEnv>(options?: HonoS
107107
if (basename !== "/") {
108108
console.log(`🔗 http://127.0.0.1:${info.port}${basename}`);
109109
}
110+
111+
console.log(`🏎️ Server started in ${Date.now() - startTime}ms`);
110112
}),
111113
port: options?.port || Number(process.env.PORT) || 3000,
112114
defaultLogger: options?.defaultLogger ?? true,

src/dev.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ export function reactRouterHonoServer(options: ReactRouterHonoServerPluginOption
144144

145145
let reactRouterBuildFile = pluginConfig.serverBuildFile;
146146

147-
// TODO: Useless now
148147
if (reactRouterBuildFile === "index.js") {
149148
reactRouterBuildFile = "assets/server-build.js";
150149
}
@@ -187,21 +186,30 @@ export function reactRouterHonoServer(options: ReactRouterHonoServerPluginOption
187186

188187
return "index.js";
189188
},
190-
// not invoked when target is webworker (single file output) TODO: Useless now
189+
// not invoked when target is webworker (single file output)
191190
chunkFileNames: (chunk) => {
192191
if (chunk.name === "server-build") {
193192
return reactRouterBuildFile;
194193
}
195194
return "assets/[name]-[hash].js";
196195
},
196+
manualChunks:
197+
runtime !== "cloudflare"
198+
? (id) => {
199+
if (id.includes(REACT_ROUTER_VIRTUAL_MODULE_ID)) {
200+
return "server-build";
201+
}
202+
203+
if (id.includes(pluginConfig!.serverEntryPoint)) {
204+
return "server";
205+
}
206+
207+
return "chunk";
208+
}
209+
: undefined,
197210
// We are doing that because we build a single file that only exports the Hono server
198211
// RR needs its exports for prerendering
199-
footer: (chunk) => {
200-
if (!chunk.isEntry) {
201-
return "";
202-
}
203-
return REACT_ROUTER_EXPORT;
204-
},
212+
footer: runtime === "cloudflare" ? REACT_ROUTER_EXPORT : undefined,
205213
},
206214
},
207215
},

0 commit comments

Comments
 (0)