diff --git a/.changeset/modern-buses-think.md b/.changeset/modern-buses-think.md new file mode 100644 index 000000000..24e50e787 --- /dev/null +++ b/.changeset/modern-buses-think.md @@ -0,0 +1,5 @@ +--- +"@opennextjs/cloudflare": patch +--- + +fix(patches): Update patchInstrumentation and loadManifest to work with Next 15.4 diff --git a/packages/cloudflare/src/cli/build/patches/plugins/instrumentation.spec.ts b/packages/cloudflare/src/cli/build/patches/plugins/instrumentation.spec.ts index b71ba339f..b34930b58 100644 --- a/packages/cloudflare/src/cli/build/patches/plugins/instrumentation.spec.ts +++ b/packages/cloudflare/src/cli/build/patches/plugins/instrumentation.spec.ts @@ -1,7 +1,7 @@ import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js"; import { describe, expect, test } from "vitest"; -import { getNext14Rule, getNext15Rule } from "./instrumentation.js"; +import { getNext14Rule, getNext15Rule, getNext154Rule } from "./instrumentation.js"; describe("LoadInstrumentationModule (Next15)", () => { const code = ` @@ -96,3 +96,59 @@ describe("prepareImpl (Next14)", () => { `); }); }); + +describe("getInstrumenationModule (Next15.4)", () => { + const code = ` + async function getInstrumentationModule(projectDir, distDir) { + if (cachedInstrumentationModule) { + return cachedInstrumentationModule; + } + try { + cachedInstrumentationModule = (0, _interopdefault.interopDefault)(await require(_nodepath.default.join(projectDir, distDir, "server", \`\${_constants.INSTRUMENTATION_HOOK_FILENAME}.js\`))); + return cachedInstrumentationModule; + } catch (err) { + if ((0, _iserror.default)(err) && err.code !== "ENOENT" && err.code !== "MODULE_NOT_FOUND" && err.code !== "ERR_MODULE_NOT_FOUND") { + throw err; + } + } + } + `; + + test("patch when an instrumentation file is not present", async () => { + expect(patchCode(code, getNext154Rule(null))).toMatchInlineSnapshot(` + "async function getInstrumentationModule(projectDir, distDir) { + if (cachedInstrumentationModule) { + return cachedInstrumentationModule; + } + try { + cachedInstrumentationModule = null; + return cachedInstrumentationModule; + } catch (err) { + if ((0, _iserror.default)(err) && err.code !== "ENOENT" && err.code !== "MODULE_NOT_FOUND" && err.code !== "ERR_MODULE_NOT_FOUND") { + throw err; + } + } + } + " + `); + }); + + test("patch when an instrumentation file is present", async () => { + expect(patchCode(code, getNext154Rule("/_file_exists_/instrumentation.js"))).toMatchInlineSnapshot(` + "async function getInstrumentationModule(projectDir, distDir) { + if (cachedInstrumentationModule) { + return cachedInstrumentationModule; + } + try { + cachedInstrumentationModule = require('/_file_exists_/instrumentation.js'); + return cachedInstrumentationModule; + } catch (err) { + if ((0, _iserror.default)(err) && err.code !== "ENOENT" && err.code !== "MODULE_NOT_FOUND" && err.code !== "ERR_MODULE_NOT_FOUND") { + throw err; + } + } + } + " + `); + }); +}); diff --git a/packages/cloudflare/src/cli/build/patches/plugins/instrumentation.ts b/packages/cloudflare/src/cli/build/patches/plugins/instrumentation.ts index 74f64754b..812e7aea4 100644 --- a/packages/cloudflare/src/cli/build/patches/plugins/instrumentation.ts +++ b/packages/cloudflare/src/cli/build/patches/plugins/instrumentation.ts @@ -4,12 +4,28 @@ import { join } from "node:path"; import { type BuildOptions, getPackagePath } from "@opennextjs/aws/build/helper.js"; import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js"; import type { ContentUpdater, Plugin } from "@opennextjs/aws/plugins/content-updater.js"; +import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js"; import { normalizePath } from "../../utils/normalize-path.js"; export function patchInstrumentation(updater: ContentUpdater, buildOpts: BuildOptions): Plugin { const builtInstrumentationPath = getBuiltInstrumentationPath(buildOpts); + updater.updateContent("patch-instrumentation-next15-4", [ + { + field: { + filter: getCrossPlatformPathRegex( + String.raw`/server/lib/router-utils/instrumentation-globals.external\.js$`, + { + escape: false, + } + ), + contentFilter: /getInstrumentationModule\(/, + callback: ({ contents }) => patchCode(contents, getNext154Rule(builtInstrumentationPath)), + }, + }, + ]); + updater.updateContent("patch-instrumentation-next15", [ { field: { @@ -36,6 +52,28 @@ export function patchInstrumentation(updater: ContentUpdater, buildOpts: BuildOp }; } +export function getNext154Rule(builtInstrumentationPath: string | null) { + return ` +rule: + kind: expression_statement + has: + kind: assignment_expression + all: + - has: { pattern: "cachedInstrumentationModule" } + - has: { kind: call_expression, regex: "INSTRUMENTATION_HOOK_FILENAME"} + inside: + kind: try_statement + stopBy: end + has: { regex: "return cachedInstrumentationModule" } + inside: + kind: function_declaration + stopBy: end + has: { field: name, pattern: getInstrumentationModule } +fix: |- + cachedInstrumentationModule = ${builtInstrumentationPath ? `require('${builtInstrumentationPath}')` : "null"}; +`; +} + export function getNext15Rule(builtInstrumentationPath: string | null) { return ` rule: diff --git a/packages/cloudflare/src/cli/build/patches/plugins/load-manifest.ts b/packages/cloudflare/src/cli/build/patches/plugins/load-manifest.ts index 960cfe9f1..669397ee1 100644 --- a/packages/cloudflare/src/cli/build/patches/plugins/load-manifest.ts +++ b/packages/cloudflare/src/cli/build/patches/plugins/load-manifest.ts @@ -39,7 +39,9 @@ async function getLoadManifestRule(buildOpts: BuildOptions) { const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts)); const dotNextDir = join(baseDir, ".next"); - const manifests = await glob(join(dotNextDir, "**/*-manifest.json"), { windowsPathsNoEscape: true }); + const manifests = await glob(join(dotNextDir, "**/{*-manifest,required-server-files}.json"), { + windowsPathsNoEscape: true, + }); const returnManifests = ( await Promise.all( @@ -62,6 +64,9 @@ function loadManifest($PATH, $$$ARGS) { fix: ` function loadManifest($PATH, $$$ARGS) { $PATH = $PATH.replaceAll(${JSON.stringify(sep)}, ${JSON.stringify(posix.sep)}); + if ($PATH === "/.next/BUILD_ID") { + return process.env.NEXT_BUILD_ID; + } ${returnManifests} throw new Error(\`Unexpected loadManifest(\${$PATH}) call!\`); }`,