Skip to content

Commit d18cd9d

Browse files
authored
fix(patches): Update patchInstrumentation and loadManifest to work with Next 15.4 (#795)
1 parent ea25f6a commit d18cd9d

File tree

4 files changed

+106
-2
lines changed

4 files changed

+106
-2
lines changed

.changeset/modern-buses-think.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@opennextjs/cloudflare": patch
3+
---
4+
5+
fix(patches): Update patchInstrumentation and loadManifest to work with Next 15.4

packages/cloudflare/src/cli/build/patches/plugins/instrumentation.spec.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
22
import { describe, expect, test } from "vitest";
33

4-
import { getNext14Rule, getNext15Rule } from "./instrumentation.js";
4+
import { getNext14Rule, getNext15Rule, getNext154Rule } from "./instrumentation.js";
55

66
describe("LoadInstrumentationModule (Next15)", () => {
77
const code = `
@@ -96,3 +96,59 @@ describe("prepareImpl (Next14)", () => {
9696
`);
9797
});
9898
});
99+
100+
describe("getInstrumenationModule (Next15.4)", () => {
101+
const code = `
102+
async function getInstrumentationModule(projectDir, distDir) {
103+
if (cachedInstrumentationModule) {
104+
return cachedInstrumentationModule;
105+
}
106+
try {
107+
cachedInstrumentationModule = (0, _interopdefault.interopDefault)(await require(_nodepath.default.join(projectDir, distDir, "server", \`\${_constants.INSTRUMENTATION_HOOK_FILENAME}.js\`)));
108+
return cachedInstrumentationModule;
109+
} catch (err) {
110+
if ((0, _iserror.default)(err) && err.code !== "ENOENT" && err.code !== "MODULE_NOT_FOUND" && err.code !== "ERR_MODULE_NOT_FOUND") {
111+
throw err;
112+
}
113+
}
114+
}
115+
`;
116+
117+
test("patch when an instrumentation file is not present", async () => {
118+
expect(patchCode(code, getNext154Rule(null))).toMatchInlineSnapshot(`
119+
"async function getInstrumentationModule(projectDir, distDir) {
120+
if (cachedInstrumentationModule) {
121+
return cachedInstrumentationModule;
122+
}
123+
try {
124+
cachedInstrumentationModule = null;
125+
return cachedInstrumentationModule;
126+
} catch (err) {
127+
if ((0, _iserror.default)(err) && err.code !== "ENOENT" && err.code !== "MODULE_NOT_FOUND" && err.code !== "ERR_MODULE_NOT_FOUND") {
128+
throw err;
129+
}
130+
}
131+
}
132+
"
133+
`);
134+
});
135+
136+
test("patch when an instrumentation file is present", async () => {
137+
expect(patchCode(code, getNext154Rule("/_file_exists_/instrumentation.js"))).toMatchInlineSnapshot(`
138+
"async function getInstrumentationModule(projectDir, distDir) {
139+
if (cachedInstrumentationModule) {
140+
return cachedInstrumentationModule;
141+
}
142+
try {
143+
cachedInstrumentationModule = require('/_file_exists_/instrumentation.js');
144+
return cachedInstrumentationModule;
145+
} catch (err) {
146+
if ((0, _iserror.default)(err) && err.code !== "ENOENT" && err.code !== "MODULE_NOT_FOUND" && err.code !== "ERR_MODULE_NOT_FOUND") {
147+
throw err;
148+
}
149+
}
150+
}
151+
"
152+
`);
153+
});
154+
});

packages/cloudflare/src/cli/build/patches/plugins/instrumentation.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,28 @@ import { join } from "node:path";
44
import { type BuildOptions, getPackagePath } from "@opennextjs/aws/build/helper.js";
55
import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
66
import type { ContentUpdater, Plugin } from "@opennextjs/aws/plugins/content-updater.js";
7+
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
78

89
import { normalizePath } from "../../utils/normalize-path.js";
910

1011
export function patchInstrumentation(updater: ContentUpdater, buildOpts: BuildOptions): Plugin {
1112
const builtInstrumentationPath = getBuiltInstrumentationPath(buildOpts);
1213

14+
updater.updateContent("patch-instrumentation-next15-4", [
15+
{
16+
field: {
17+
filter: getCrossPlatformPathRegex(
18+
String.raw`/server/lib/router-utils/instrumentation-globals.external\.js$`,
19+
{
20+
escape: false,
21+
}
22+
),
23+
contentFilter: /getInstrumentationModule\(/,
24+
callback: ({ contents }) => patchCode(contents, getNext154Rule(builtInstrumentationPath)),
25+
},
26+
},
27+
]);
28+
1329
updater.updateContent("patch-instrumentation-next15", [
1430
{
1531
field: {
@@ -36,6 +52,28 @@ export function patchInstrumentation(updater: ContentUpdater, buildOpts: BuildOp
3652
};
3753
}
3854

55+
export function getNext154Rule(builtInstrumentationPath: string | null) {
56+
return `
57+
rule:
58+
kind: expression_statement
59+
has:
60+
kind: assignment_expression
61+
all:
62+
- has: { pattern: "cachedInstrumentationModule" }
63+
- has: { kind: call_expression, regex: "INSTRUMENTATION_HOOK_FILENAME"}
64+
inside:
65+
kind: try_statement
66+
stopBy: end
67+
has: { regex: "return cachedInstrumentationModule" }
68+
inside:
69+
kind: function_declaration
70+
stopBy: end
71+
has: { field: name, pattern: getInstrumentationModule }
72+
fix: |-
73+
cachedInstrumentationModule = ${builtInstrumentationPath ? `require('${builtInstrumentationPath}')` : "null"};
74+
`;
75+
}
76+
3977
export function getNext15Rule(builtInstrumentationPath: string | null) {
4078
return `
4179
rule:

packages/cloudflare/src/cli/build/patches/plugins/load-manifest.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ async function getLoadManifestRule(buildOpts: BuildOptions) {
3939
const baseDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts));
4040
const dotNextDir = join(baseDir, ".next");
4141

42-
const manifests = await glob(join(dotNextDir, "**/*-manifest.json"), { windowsPathsNoEscape: true });
42+
const manifests = await glob(join(dotNextDir, "**/{*-manifest,required-server-files}.json"), {
43+
windowsPathsNoEscape: true,
44+
});
4345

4446
const returnManifests = (
4547
await Promise.all(
@@ -62,6 +64,9 @@ function loadManifest($PATH, $$$ARGS) {
6264
fix: `
6365
function loadManifest($PATH, $$$ARGS) {
6466
$PATH = $PATH.replaceAll(${JSON.stringify(sep)}, ${JSON.stringify(posix.sep)});
67+
if ($PATH === "/.next/BUILD_ID") {
68+
return process.env.NEXT_BUILD_ID;
69+
}
6570
${returnManifests}
6671
throw new Error(\`Unexpected loadManifest(\${$PATH}) call!\`);
6772
}`,

0 commit comments

Comments
 (0)