Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/cloudflare/src/cli/build/bundle-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { patchFetchCacheSetMissingWaitUntil } from "./patches/plugins/fetch-cach
import { inlineFindDir } from "./patches/plugins/find-dir.js";
import { patchInstrumentation } from "./patches/plugins/instrumentation.js";
import { inlineLoadManifest } from "./patches/plugins/load-manifest.js";
import { inlineNodeModuleLoader } from "./patches/plugins/node-module-loader.js";
import { handleOptionalDependencies } from "./patches/plugins/optional-deps.js";
import { patchDepdDeprecations } from "./patches/plugins/patch-depd-deprecations.js";
import { fixRequire } from "./patches/plugins/require.js";
Expand Down Expand Up @@ -89,6 +90,7 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {
plugins: [
shimRequireHook(buildOpts),
inlineRequirePage(updater, buildOpts),
inlineNodeModuleLoader(updater, buildOpts),
setWranglerExternal(),
fixRequire(updater),
handleOptionalDependencies(optionalDependencies),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { readFile } from "node:fs/promises";
import { join } from "node:path";

import { type BuildOptions, getPackagePath } from "@opennextjs/aws/build/helper.js";
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";

import { normalizePath } from "../../utils/normalize-path.js";
import { patchCode, type RuleConfig } from "../ast/util.js";
import type { ContentUpdater } from "./content-updater.js";

export function inlineNodeModuleLoader(updater: ContentUpdater, buildOpts: BuildOptions) {
return updater.updateContent(
"inline-node-module-loader",
{
filter: getCrossPlatformPathRegex(
String.raw`/next/dist/server/lib/module-loader/node-module-loader\.js$`,
{ escape: false }
),
contentFilter: /class NodeModuleLoader {/,
},
async ({ contents }) => patchCode(contents, await getRule(buildOpts))
);
}

async function getRule(buildOpts: BuildOptions) {
const { outputDir } = buildOpts;
const serverDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");

const pagesManifestFile = join(serverDir, "pages-manifest.json");

let pagesManifests: string[] = [];
try {
pagesManifests = Object.values(JSON.parse(await readFile(pagesManifestFile, "utf-8")));
} catch {
// The file does not exist
pagesManifests = [];
}

const manifests = pagesManifests.map((path) => normalizePath(path));

const files = manifests.filter((file) => file.endsWith(".js"));

// Inline fs access and dynamic requires that are not supported by workerd.
const fnBody = `
${files
.map(
(file) => `if (id.endsWith("${file}")) {
return require(${JSON.stringify(join(serverDir, file))});
}`
)
.join("\n")}
`;

return {
rule: {
pattern: `class NodeModuleLoader {
async load($ID) {
$$$_BODY
}
}`,
},
fix: `class NodeModuleLoader {
async load($ID) {
${fnBody}
}
}`,
} satisfies RuleConfig;
}