Skip to content

Commit e79f09c

Browse files
authored
refactor: patch evalManifest using ast-grep (#391)
1 parent c5e9bff commit e79f09c

File tree

5 files changed

+72
-53
lines changed

5 files changed

+72
-53
lines changed

packages/cloudflare/src/cli/build/bundle-server.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ import { patchVercelOgLibrary } from "./patches/ast/patch-vercel-og-library.js";
1010
import { patchWebpackRuntime } from "./patches/ast/webpack-runtime.js";
1111
import * as patches from "./patches/index.js";
1212
import { ContentUpdater } from "./patches/plugins/content-updater.js";
13+
import { inlineEvalManifest } from "./patches/plugins/eval-manifest.js";
1314
import { patchFetchCacheSetMissingWaitUntil } from "./patches/plugins/fetch-cache-wait-until.js";
1415
import { patchLoadInstrumentation } from "./patches/plugins/load-instrumentation.js";
1516
import { handleOptionalDependencies } from "./patches/plugins/optional-deps.js";
1617
import { fixRequire } from "./patches/plugins/require.js";
1718
import { shimRequireHook } from "./patches/plugins/require-hook.js";
18-
import { inlineRequirePagePlugin } from "./patches/plugins/require-page.js";
19+
import { inlineRequirePage } from "./patches/plugins/require-page.js";
1920
import { setWranglerExternal } from "./patches/plugins/wrangler-external.js";
2021
import { normalizePath, patchCodeWithValidations } from "./utils/index.js";
2122

@@ -83,12 +84,13 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {
8384
conditions: [],
8485
plugins: [
8586
shimRequireHook(buildOpts),
86-
inlineRequirePagePlugin(updater, buildOpts),
87+
inlineRequirePage(updater, buildOpts),
8788
setWranglerExternal(),
8889
fixRequire(updater),
8990
handleOptionalDependencies(optionalDependencies),
9091
patchLoadInstrumentation(updater),
9192
patchFetchCacheSetMissingWaitUntil(updater),
93+
inlineEvalManifest(updater, buildOpts),
9294
// Apply updater updaters, must be the last plugin
9395
updater.plugin,
9496
],
@@ -194,7 +196,6 @@ export async function updateWorkerBundledCode(
194196
["`buildId` function", (code) => patches.patchBuildId(code, buildOpts)],
195197
["`loadManifest` function", (code) => patches.patchLoadManifest(code, buildOpts)],
196198
["`findDir` function", (code) => patches.patchFindDir(code, buildOpts)],
197-
["`evalManifest` function", (code) => patches.inlineEvalManifest(code, buildOpts)],
198199
["cacheHandler", (code) => patches.patchCache(code, buildOpts)],
199200
[
200201
"'require(this.middlewareManifestPath)'",
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* Inline `evalManifest` as it relies on `readFileSync` and `runInNewContext`
3+
* that are not supported by workerd.
4+
*/
5+
6+
import { join, relative } from "node:path";
7+
8+
import { type BuildOptions, getPackagePath } from "@opennextjs/aws/build/helper.js";
9+
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
10+
import { glob } from "glob";
11+
12+
import { normalizePath } from "../../utils/normalize-path.js";
13+
import { patchCode, type RuleConfig } from "../ast/util.js";
14+
import type { ContentUpdater } from "./content-updater.js";
15+
16+
export function inlineEvalManifest(updater: ContentUpdater, buildOpts: BuildOptions) {
17+
return updater.updateContent(
18+
"inline-eval-manifest",
19+
{
20+
filter: getCrossPlatformPathRegex(String.raw`/next/dist/server/load-manifest\.js$`, { escape: false }),
21+
contentFilter: /function evalManifest\(/,
22+
},
23+
async ({ contents }) => patchCode(contents, await getRule(buildOpts))
24+
);
25+
}
26+
27+
async function getRule(buildOpts: BuildOptions) {
28+
const { outputDir } = buildOpts;
29+
30+
const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next");
31+
const appDir = join(baseDir, "server/app");
32+
const manifests = await glob(join(baseDir, "**/*_client-reference-manifest.js"));
33+
34+
const returnManifests = manifests
35+
.map((manifest) => {
36+
const endsWith = normalizePath(relative(baseDir, manifest));
37+
const key = normalizePath("/" + relative(appDir, manifest)).replace(
38+
"_client-reference-manifest.js",
39+
""
40+
);
41+
return `
42+
if ($PATH.endsWith("${endsWith}")) {
43+
require(${JSON.stringify(manifest)});
44+
return {
45+
__RSC_MANIFEST: {
46+
"${key}": globalThis.__RSC_MANIFEST["${key}"],
47+
},
48+
};
49+
}
50+
`;
51+
})
52+
.join("\n");
53+
54+
return {
55+
rule: {
56+
pattern: `
57+
function evalManifest($PATH, $$$ARGS) {
58+
$$$_
59+
}`,
60+
},
61+
fix: `
62+
function evalManifest($PATH, $$$ARGS) {
63+
${returnManifests}
64+
throw new Error("Unknown evalManifest: " + $PATH);
65+
}`,
66+
} satisfies RuleConfig;
67+
}

packages/cloudflare/src/cli/build/patches/plugins/require-page.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
77
import { patchCode, type RuleConfig } from "../ast/util.js";
88
import type { ContentUpdater } from "./content-updater.js";
99

10-
export function inlineRequirePagePlugin(updater: ContentUpdater, buildOpts: BuildOptions) {
10+
export function inlineRequirePage(updater: ContentUpdater, buildOpts: BuildOptions) {
1111
return updater.updateContent(
1212
"inline-require-page",
1313
{

packages/cloudflare/src/cli/build/patches/to-investigate/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
export * from "./inline-eval-manifest.js";
21
export * from "./inline-middleware-manifest-require.js";
32
export * from "./patch-exception-bubbling.js";
43
export * from "./patch-find-dir.js";

packages/cloudflare/src/cli/build/patches/to-investigate/inline-eval-manifest.ts

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)