Skip to content

Commit e29a59f

Browse files
committed
refactor: migrate the requirePage patch to ast-grep
1 parent 94e5969 commit e29a59f

File tree

5 files changed

+95
-58
lines changed

5 files changed

+95
-58
lines changed

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { build, Plugin } from "esbuild";
1010

1111
import { patchOptionalDependencies } from "./patches/ast/optional-deps.js";
1212
import * as patches from "./patches/index.js";
13+
import InlineRequirePagePlugin from "./patches/plugins/require-page.js";
1314
import { normalizePath, patchCodeWithValidations } from "./utils/index.js";
1415

1516
/** The dist directory of the Cloudflare adapter package */
@@ -48,8 +49,17 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {
4849
format: "esm",
4950
target: "esnext",
5051
minify: false,
51-
plugins: [createFixRequiresESBuildPlugin(buildOpts)],
52-
external: ["./middleware/handler.mjs", "caniuse-lite"],
52+
plugins: [createFixRequiresESBuildPlugin(buildOpts), InlineRequirePagePlugin(buildOpts)],
53+
external: [
54+
"./middleware/handler.mjs",
55+
// Next optional dependencies.
56+
"caniuse-lite",
57+
"jimp",
58+
"probe-image-size",
59+
// Dependencies handled by wrangler.
60+
"*.bin",
61+
"*.wasm?module",
62+
],
5363
alias: {
5464
// Note: we apply an empty shim to next/dist/compiled/ws because it generates two `eval`s:
5565
// eval("require")("bufferutil");
@@ -146,7 +156,6 @@ async function updateWorkerBundledCode(workerOutputFile: string, buildOpts: Buil
146156
["require", patches.patchRequire],
147157
["`buildId` function", (code) => patches.patchBuildId(code, buildOpts)],
148158
["`loadManifest` function", (code) => patches.patchLoadManifest(code, buildOpts)],
149-
["next's require", (code) => patches.inlineNextRequire(code, buildOpts)],
150159
["`findDir` function", (code) => patches.patchFindDir(code, buildOpts)],
151160
["`evalManifest` function", (code) => patches.inlineEvalManifest(code, buildOpts)],
152161
["cacheHandler", (code) => patches.patchCache(code, buildOpts)],

packages/cloudflare/src/cli/build/patches/ast/optional-deps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ rule:
1616
pattern: $MOD
1717
kind: string_fragment
1818
stopBy: end
19-
regex: ^caniuse-lite(/|$)
19+
regex: ^caniuse-lite(/|$)|jimp(/|$)|probe-image-size(/|$)
2020
not:
2121
inside:
2222
kind: try_statement
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { existsSync, readFileSync } from "node:fs";
2+
import { readFile } from "node:fs/promises";
3+
import { join } from "node:path";
4+
5+
import { type BuildOptions, getPackagePath } from "@opennextjs/aws/build/helper.js";
6+
import type { PluginBuild } from "esbuild";
7+
8+
import { patchCode, type RuleConfig } from "../ast/util.js";
9+
10+
export default function InlineRequirePagePlugin(buildOpts: BuildOptions) {
11+
return {
12+
name: "inline-require-page",
13+
14+
setup: async (build: PluginBuild) => {
15+
build.onLoad({ filter: /\/next\/dist\/server\/require\.js$/ }, async ({ path }) => {
16+
const jsCode = await readFile(path, "utf8");
17+
if (/function requirePage\(/.test(jsCode)) {
18+
return { contents: patchCode(jsCode, getRule(buildOpts)) };
19+
}
20+
});
21+
},
22+
};
23+
}
24+
25+
function getRule(buildOpts: BuildOptions) {
26+
// Load manifests
27+
const { outputDir } = buildOpts;
28+
const serverDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
29+
30+
const pagesManifestFile = join(serverDir, "pages-manifest.json");
31+
const appPathsManifestFile = join(serverDir, "app-paths-manifest.json");
32+
33+
const pagesManifests: string[] = existsSync(pagesManifestFile)
34+
? Object.values(JSON.parse(readFileSync(pagesManifestFile, "utf-8")))
35+
: [];
36+
const appPathsManifests: string[] = existsSync(appPathsManifestFile)
37+
? Object.values(JSON.parse(readFileSync(appPathsManifestFile, "utf-8")))
38+
: [];
39+
const manifests = pagesManifests.concat(appPathsManifests);
40+
41+
const htmlFiles = manifests.filter((file) => file.endsWith(".html"));
42+
const jsFiles = manifests.filter((file) => file.endsWith(".js"));
43+
44+
const fnBody = `
45+
// html
46+
${htmlFiles
47+
.map(
48+
(file) => `if (pagePath.endsWith("${file}")) {
49+
return ${JSON.stringify(readFileSync(join(serverDir, file), "utf-8"))};
50+
}`
51+
)
52+
.join("\n")}
53+
// js
54+
process.env.__NEXT_PRIVATE_RUNTIME_TYPE = isAppPath ? 'app' : 'pages';
55+
try {
56+
${jsFiles
57+
.map(
58+
(file) => `if (pagePath.endsWith("${file}")) {
59+
return require(${JSON.stringify(join(serverDir, file))});
60+
}`
61+
)
62+
.join("\n")}
63+
} finally {
64+
process.env.__NEXT_PRIVATE_RUNTIME_TYPE = '';
65+
}
66+
`;
67+
68+
return {
69+
rule: {
70+
pattern: `
71+
function requirePage($PAGE, $DIST_DIR, $IS_APPP_ATH) {
72+
const $_ = getPagePath($$$ARGS);
73+
$$$
74+
}`,
75+
},
76+
fix: `
77+
function requirePage($PAGE, $DIST_DIR, $IS_APPP_ATH) {
78+
const pagePath = getPagePath($$$ARGS);
79+
${fnBody}
80+
}`,
81+
} satisfies RuleConfig;
82+
}

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,6 +1,5 @@
11
export * from "./inline-eval-manifest.js";
22
export * from "./inline-middleware-manifest-require.js";
3-
export * from "./inline-next-require.js";
43
export * from "./patch-exception-bubbling.js";
54
export * from "./patch-find-dir.js";
65
export * from "./patch-load-instrumentation-module.js";

packages/cloudflare/src/cli/build/patches/to-investigate/inline-next-require.ts

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

0 commit comments

Comments
 (0)