Skip to content

Commit

Permalink
feat: use incremental cache during rendering (#64)
Browse files Browse the repository at this point in the history
* feat: use incremental cache during rendering
* patch exception bubbling
  • Loading branch information
james-elicx authored Oct 7, 2024
1 parent bcaaec6 commit ba9af72
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
8 changes: 4 additions & 4 deletions packages/cloudflare/src/cli/build/build-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import { Config } from "../config";
import { copyPackageCliFiles } from "./patches/investigated/copy-package-cli-files";
import { fileURLToPath } from "node:url";
import { inlineEvalManifest } from "./patches/to-investigate/inline-eval-manifest";
import { inlineMiddlewareManifestRequire } from "./patches/to-investigate/inline-middleware-manifest-require";
import { inlineNextRequire } from "./patches/to-investigate/inline-next-require";
import { patchCache } from "./patches/investigated/patch-cache";
import { patchExceptionBubbling } from "./patches/to-investigate/patch-exception-bubbling";
import { patchFindDir } from "./patches/to-investigate/patch-find-dir";
import { patchReadFile } from "./patches/to-investigate/patch-read-file";
import { patchRequire } from "./patches/investigated/patch-require";
Expand Down Expand Up @@ -90,10 +92,6 @@ export async function buildWorker(config: Config): Promise<void> {
// Note: we need the __non_webpack_require__ variable declared as it is used by next-server:
// https://github.com/vercel/next.js/blob/be0c3283/packages/next/src/server/next-server.ts#L116-L119
__non_webpack_require__: "require",
// 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
// 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
// that's wht we enable it
"process.env.NEXT_PRIVATE_MINIMAL_MODE": "true",
// Ask mhart if he can explain why the `define`s below are necessary
"process.env.NEXT_RUNTIME": '"nodejs"',
"process.env.NODE_ENV": '"production"',
Expand Down Expand Up @@ -166,6 +164,8 @@ async function updateWorkerBundledCode(workerOutputFile: string, config: Config)
patchedCode = patchFindDir(patchedCode, config);
patchedCode = inlineEvalManifest(patchedCode, config);
patchedCode = patchCache(patchedCode, config);
patchedCode = inlineMiddlewareManifestRequire(patchedCode, config);
patchedCode = patchExceptionBubbling(patchedCode);

await writeFile(workerOutputFile, patchedCode);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import path from "node:path";
* Install the cloudflare KV cache handler
*/
export function patchCache(code: string, config: Config): string {
console.log("# patchCached");
console.log("# patchCache");

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { existsSync, readFileSync } from "node:fs";
import { Config } from "../../../config";
import path from "node:path";

/**
* Inlines the middleware manifest from the build output to prevent a dynamic require statement
* as they result in runtime failures.
*/
export function inlineMiddlewareManifestRequire(code: string, config: Config) {
console.log("# inlineMiddlewareManifestRequire");

const middlewareManifestPath = path.join(config.paths.standaloneAppServer, "middleware-manifest.json");

const middlewareManifest = existsSync(middlewareManifestPath)
? JSON.parse(readFileSync(middlewareManifestPath, "utf-8"))
: {};

const patchedCode = code.replace(
"require(this.middlewareManifestPath)",
JSON.stringify(middlewareManifest)
);

if (patchedCode === code) {
throw new Error("Patch `inlineMiddlewareManifestRequire` not applied");
}

return patchedCode;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* When using SSG and `dynamicParams = false`, Next.js throws a NoFallbackError. This error is
* bubbled up by default in Node.js servers, however this causes issues in the workerd with
* the current response handling and streaming implementation we have, and leads to hanging
* promises.
*/
export function patchExceptionBubbling(code: string) {
console.log("# patchExceptionBubbling");

const patchedCode = code.replace('_nextBubbleNoFallback = "1"', "_nextBubbleNoFallback = undefined");

if (patchedCode === code) {
throw new Error("Patch `patchExceptionBubbling` not applied");
}

return patchedCode;
}

0 comments on commit ba9af72

Please sign in to comment.