Skip to content

Commit ba9af72

Browse files
authored
feat: use incremental cache during rendering (#64)
* feat: use incremental cache during rendering * patch exception bubbling
1 parent bcaaec6 commit ba9af72

File tree

4 files changed

+50
-5
lines changed

4 files changed

+50
-5
lines changed

packages/cloudflare/src/cli/build/build-worker.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import { Config } from "../config";
55
import { copyPackageCliFiles } from "./patches/investigated/copy-package-cli-files";
66
import { fileURLToPath } from "node:url";
77
import { inlineEvalManifest } from "./patches/to-investigate/inline-eval-manifest";
8+
import { inlineMiddlewareManifestRequire } from "./patches/to-investigate/inline-middleware-manifest-require";
89
import { inlineNextRequire } from "./patches/to-investigate/inline-next-require";
910
import { patchCache } from "./patches/investigated/patch-cache";
11+
import { patchExceptionBubbling } from "./patches/to-investigate/patch-exception-bubbling";
1012
import { patchFindDir } from "./patches/to-investigate/patch-find-dir";
1113
import { patchReadFile } from "./patches/to-investigate/patch-read-file";
1214
import { patchRequire } from "./patches/investigated/patch-require";
@@ -90,10 +92,6 @@ export async function buildWorker(config: Config): Promise<void> {
9092
// Note: we need the __non_webpack_require__ variable declared as it is used by next-server:
9193
// https://github.com/vercel/next.js/blob/be0c3283/packages/next/src/server/next-server.ts#L116-L119
9294
__non_webpack_require__: "require",
93-
// The next.js server can run in minimal mode: https://github.com/vercel/next.js/blob/aa90fe9bb/packages/next/src/server/base-server.ts#L510-L511
94-
// this avoids some extra (/problematic) `require` calls, such as here: https://github.com/vercel/next.js/blob/aa90fe9bb/packages/next/src/server/next-server.ts#L1259
95-
// that's wht we enable it
96-
"process.env.NEXT_PRIVATE_MINIMAL_MODE": "true",
9795
// Ask mhart if he can explain why the `define`s below are necessary
9896
"process.env.NEXT_RUNTIME": '"nodejs"',
9997
"process.env.NODE_ENV": '"production"',
@@ -166,6 +164,8 @@ async function updateWorkerBundledCode(workerOutputFile: string, config: Config)
166164
patchedCode = patchFindDir(patchedCode, config);
167165
patchedCode = inlineEvalManifest(patchedCode, config);
168166
patchedCode = patchCache(patchedCode, config);
167+
patchedCode = inlineMiddlewareManifestRequire(patchedCode, config);
168+
patchedCode = patchExceptionBubbling(patchedCode);
169169

170170
await writeFile(workerOutputFile, patchedCode);
171171
}

packages/cloudflare/src/cli/build/patches/investigated/patch-cache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import path from "node:path";
55
* Install the cloudflare KV cache handler
66
*/
77
export function patchCache(code: string, config: Config): string {
8-
console.log("# patchCached");
8+
console.log("# patchCache");
99

1010
const cacheHandler = path.join(config.paths.internalPackage, "cli", "cache-handler.mjs");
1111

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { existsSync, readFileSync } from "node:fs";
2+
import { Config } from "../../../config";
3+
import path from "node:path";
4+
5+
/**
6+
* Inlines the middleware manifest from the build output to prevent a dynamic require statement
7+
* as they result in runtime failures.
8+
*/
9+
export function inlineMiddlewareManifestRequire(code: string, config: Config) {
10+
console.log("# inlineMiddlewareManifestRequire");
11+
12+
const middlewareManifestPath = path.join(config.paths.standaloneAppServer, "middleware-manifest.json");
13+
14+
const middlewareManifest = existsSync(middlewareManifestPath)
15+
? JSON.parse(readFileSync(middlewareManifestPath, "utf-8"))
16+
: {};
17+
18+
const patchedCode = code.replace(
19+
"require(this.middlewareManifestPath)",
20+
JSON.stringify(middlewareManifest)
21+
);
22+
23+
if (patchedCode === code) {
24+
throw new Error("Patch `inlineMiddlewareManifestRequire` not applied");
25+
}
26+
27+
return patchedCode;
28+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* When using SSG and `dynamicParams = false`, Next.js throws a NoFallbackError. This error is
3+
* bubbled up by default in Node.js servers, however this causes issues in the workerd with
4+
* the current response handling and streaming implementation we have, and leads to hanging
5+
* promises.
6+
*/
7+
export function patchExceptionBubbling(code: string) {
8+
console.log("# patchExceptionBubbling");
9+
10+
const patchedCode = code.replace('_nextBubbleNoFallback = "1"', "_nextBubbleNoFallback = undefined");
11+
12+
if (patchedCode === code) {
13+
throw new Error("Patch `patchExceptionBubbling` not applied");
14+
}
15+
16+
return patchedCode;
17+
}

0 commit comments

Comments
 (0)