diff --git a/packages/cloudflare/src/cli/build/bundle-server.ts b/packages/cloudflare/src/cli/build/bundle-server.ts index 7e8966c1..3e185f6a 100644 --- a/packages/cloudflare/src/cli/build/bundle-server.ts +++ b/packages/cloudflare/src/cli/build/bundle-server.ts @@ -12,6 +12,7 @@ import * as patches from "./patches/index.js"; import { ContentUpdater } from "./patches/plugins/content-updater.js"; import { inlineEvalManifest } from "./patches/plugins/eval-manifest.js"; import { patchFetchCacheSetMissingWaitUntil } from "./patches/plugins/fetch-cache-wait-until.js"; +import { inlineFindDir } from "./patches/plugins/find-dir.js"; import { patchLoadInstrumentation } from "./patches/plugins/load-instrumentation.js"; import { handleOptionalDependencies } from "./patches/plugins/optional-deps.js"; import { fixRequire } from "./patches/plugins/require.js"; @@ -91,6 +92,7 @@ export async function bundleServer(buildOpts: BuildOptions): Promise { patchLoadInstrumentation(updater), patchFetchCacheSetMissingWaitUntil(updater), inlineEvalManifest(updater, buildOpts), + inlineFindDir(updater, buildOpts), // Apply updater updaters, must be the last plugin updater.plugin, ], @@ -195,7 +197,6 @@ export async function updateWorkerBundledCode( ["require", patches.patchRequire], ["`buildId` function", (code) => patches.patchBuildId(code, buildOpts)], ["`loadManifest` function", (code) => patches.patchLoadManifest(code, buildOpts)], - ["`findDir` function", (code) => patches.patchFindDir(code, buildOpts)], ["cacheHandler", (code) => patches.patchCache(code, buildOpts)], [ "'require(this.middlewareManifestPath)'", diff --git a/packages/cloudflare/src/cli/build/patches/plugins/find-dir.ts b/packages/cloudflare/src/cli/build/patches/plugins/find-dir.ts new file mode 100644 index 00000000..fa10a2ae --- /dev/null +++ b/packages/cloudflare/src/cli/build/patches/plugins/find-dir.ts @@ -0,0 +1,50 @@ +/** + * Inline `evalManifest` as it relies on `readFileSync` and `runInNewContext` + * that are not supported by workerd. + */ + +import { existsSync } from "node:fs"; +import { join } from "node:path"; + +import { type BuildOptions, getPackagePath } from "@opennextjs/aws/build/helper.js"; +import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js"; + +import { patchCode } from "../ast/util.js"; +import type { ContentUpdater } from "./content-updater.js"; + +export function inlineFindDir(updater: ContentUpdater, buildOpts: BuildOptions) { + return updater.updateContent( + "inline-find-dir", + { + filter: getCrossPlatformPathRegex(String.raw`/next/dist/lib/find-pages-dir\.js$`, { escape: false }), + contentFilter: /function findDir\(/, + }, + async ({ contents }) => patchCode(contents, await getRule(buildOpts)) + ); +} + +async function getRule(buildOpts: BuildOptions) { + const { outputDir } = buildOpts; + + const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server"); + + const appExists = existsSync(join(baseDir, "app")); + const pagesExists = existsSync(join(baseDir, "pages")); + + return ` +rule: + pattern: function findDir($DIR, $NAME) { $$$_ } +fix: |- + function findDir($DIR, $NAME) { + if ($DIR.endsWith(".next/server")) { + if ($NAME === "app") { + return ${appExists}; + } + if ($NAME === "pages") { + return ${pagesExists}; + } + } + throw new Error(\`Unexpected findDir(\${$DIR}, \${$NAME}) call!\`); + } +`; +} diff --git a/packages/cloudflare/src/cli/build/patches/to-investigate/index.ts b/packages/cloudflare/src/cli/build/patches/to-investigate/index.ts index c6fd4fe2..3050e19d 100644 --- a/packages/cloudflare/src/cli/build/patches/to-investigate/index.ts +++ b/packages/cloudflare/src/cli/build/patches/to-investigate/index.ts @@ -1,4 +1,3 @@ export * from "./inline-middleware-manifest-require.js"; export * from "./patch-exception-bubbling.js"; -export * from "./patch-find-dir.js"; export * from "./patch-read-file.js"; diff --git a/packages/cloudflare/src/cli/build/patches/to-investigate/patch-find-dir.ts b/packages/cloudflare/src/cli/build/patches/to-investigate/patch-find-dir.ts deleted file mode 100644 index d7f22a4f..00000000 --- a/packages/cloudflare/src/cli/build/patches/to-investigate/patch-find-dir.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { existsSync } from "node:fs"; -import { join } from "node:path"; - -import { type BuildOptions, getPackagePath } from "@opennextjs/aws/build/helper.js"; - -/** - * Patches `findDir` so that the next server can detect whether the `app` or `pages` directory exists - */ -export function patchFindDir(code: string, buildOpts: BuildOptions): string { - const { outputDir } = buildOpts; - - const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server"); - - return code.replace( - /function findDir\((?dir\d*), (?name\d*)\) {/, - `function findDir($dir, $name) { - if ($dir.endsWith(".next/server")) { - if ($name === "app") { - return ${existsSync(`${join(baseDir, "app")}`)}; - } - if ($name === "pages") { - return ${existsSync(`${join(baseDir, "pages")}`)}; - } - } - throw new Error("Unknown findDir call: " + $dir + " " + $name); - ` - ); -}