@opennextjs/cloudflare 0.5.7 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/build/bundle-server.js +11 -4
- package/dist/cli/build/patches/plugins/dynamic-requires.d.ts +4 -0
- package/dist/cli/build/patches/plugins/dynamic-requires.js +108 -0
- package/dist/cli/build/patches/plugins/eval-manifest.js +2 -3
- package/dist/cli/build/patches/plugins/find-dir.js +2 -3
- package/dist/cli/build/patches/plugins/load-manifest.js +2 -3
- package/dist/cli/build/patches/plugins/next-minimal.d.ts +7 -0
- package/dist/cli/build/patches/plugins/next-minimal.js +78 -0
- package/dist/cli/build/patches/plugins/next-minimal.spec.d.ts +1 -0
- package/dist/cli/build/patches/plugins/next-minimal.spec.js +71 -0
- package/dist/cli/build/utils/index.d.ts +1 -0
- package/dist/cli/build/utils/index.js +1 -0
- package/dist/cli/build/utils/needs-experimental-react.d.ts +11 -0
- package/dist/cli/build/utils/needs-experimental-react.js +5 -0
- package/package.json +1 -1
- package/dist/cli/build/patches/plugins/require-page.d.ts +0 -3
- package/dist/cli/build/patches/plugins/require-page.js +0 -70
|
@@ -9,18 +9,19 @@ import { patchWebpackRuntime } from "./patches/ast/webpack-runtime.js";
|
|
|
9
9
|
import * as patches from "./patches/index.js";
|
|
10
10
|
import { inlineBuildId } from "./patches/plugins/build-id.js";
|
|
11
11
|
import { ContentUpdater } from "./patches/plugins/content-updater.js";
|
|
12
|
+
import { inlineDynamicRequires } from "./patches/plugins/dynamic-requires.js";
|
|
12
13
|
import { inlineEvalManifest } from "./patches/plugins/eval-manifest.js";
|
|
13
14
|
import { patchFetchCacheSetMissingWaitUntil } from "./patches/plugins/fetch-cache-wait-until.js";
|
|
14
15
|
import { inlineFindDir } from "./patches/plugins/find-dir.js";
|
|
15
16
|
import { patchInstrumentation } from "./patches/plugins/instrumentation.js";
|
|
16
17
|
import { inlineLoadManifest } from "./patches/plugins/load-manifest.js";
|
|
18
|
+
import { patchNextMinimal } from "./patches/plugins/next-minimal.js";
|
|
17
19
|
import { handleOptionalDependencies } from "./patches/plugins/optional-deps.js";
|
|
18
20
|
import { patchDepdDeprecations } from "./patches/plugins/patch-depd-deprecations.js";
|
|
19
21
|
import { fixRequire } from "./patches/plugins/require.js";
|
|
20
22
|
import { shimRequireHook } from "./patches/plugins/require-hook.js";
|
|
21
|
-
import { inlineRequirePage } from "./patches/plugins/require-page.js";
|
|
22
23
|
import { setWranglerExternal } from "./patches/plugins/wrangler-external.js";
|
|
23
|
-
import { normalizePath, patchCodeWithValidations } from "./utils/index.js";
|
|
24
|
+
import { needsExperimentalReact, normalizePath, patchCodeWithValidations } from "./utils/index.js";
|
|
24
25
|
/** The dist directory of the Cloudflare adapter package */
|
|
25
26
|
const packageDistDir = path.join(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
|
26
27
|
/**
|
|
@@ -72,7 +73,7 @@ export async function bundleServer(buildOpts) {
|
|
|
72
73
|
conditions: [],
|
|
73
74
|
plugins: [
|
|
74
75
|
shimRequireHook(buildOpts),
|
|
75
|
-
|
|
76
|
+
inlineDynamicRequires(updater, buildOpts),
|
|
76
77
|
setWranglerExternal(),
|
|
77
78
|
fixRequire(updater),
|
|
78
79
|
handleOptionalDependencies(optionalDependencies),
|
|
@@ -83,6 +84,7 @@ export async function bundleServer(buildOpts) {
|
|
|
83
84
|
inlineLoadManifest(updater, buildOpts),
|
|
84
85
|
inlineBuildId(updater),
|
|
85
86
|
patchDepdDeprecations(updater),
|
|
87
|
+
patchNextMinimal(updater),
|
|
86
88
|
// Apply updater updaters, must be the last plugin
|
|
87
89
|
updater.plugin,
|
|
88
90
|
],
|
|
@@ -117,7 +119,12 @@ export async function bundleServer(buildOpts) {
|
|
|
117
119
|
// We make sure that environment variables that Next.js expects are properly defined
|
|
118
120
|
"process.env.NEXT_RUNTIME": '"nodejs"',
|
|
119
121
|
"process.env.NODE_ENV": '"production"',
|
|
120
|
-
|
|
122
|
+
// The 2 following defines are used to reduce the bundle size by removing unnecessary code
|
|
123
|
+
// Next uses different precompiled renderers (i.e. `app-page.runtime.prod.js`) based on if you use `TURBOPACK` or some experimental React features
|
|
124
|
+
// Turbopack is not supported for build at the moment, so we disable it
|
|
125
|
+
"process.env.TURBOPACK": "false",
|
|
126
|
+
// This define should be safe to use for Next 14.2+, earlier versions (13.5 and less) will cause trouble
|
|
127
|
+
"process.env.__NEXT_EXPERIMENTAL_REACT": `${needsExperimentalReact(nextConfig)}`,
|
|
121
128
|
},
|
|
122
129
|
platform: "node",
|
|
123
130
|
banner: {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
|
+
import type { Plugin } from "esbuild";
|
|
3
|
+
import type { ContentUpdater } from "./content-updater.js";
|
|
4
|
+
export declare function inlineDynamicRequires(updater: ContentUpdater, buildOpts: BuildOptions): Plugin;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join, posix, sep } from "node:path";
|
|
3
|
+
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
4
|
+
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
|
|
5
|
+
import { normalizePath } from "../../utils/normalize-path.js";
|
|
6
|
+
import { patchCode } from "../ast/util.js";
|
|
7
|
+
async function getPagesManifests(serverDir) {
|
|
8
|
+
try {
|
|
9
|
+
return Object.values(JSON.parse(await readFile(join(serverDir, "pages-manifest.json"), "utf-8")));
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
// The file does not exist
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async function getAppPathsManifests(serverDir) {
|
|
17
|
+
try {
|
|
18
|
+
return Object.values(JSON.parse(await readFile(join(serverDir, "app-paths-manifest.json"), "utf-8")));
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// The file does not exist
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function getServerDir(buildOpts) {
|
|
26
|
+
return join(buildOpts.outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
|
|
27
|
+
}
|
|
28
|
+
function getRequires(idVariable, files, serverDir) {
|
|
29
|
+
// Inline fs access and dynamic requires that are not supported by workerd.
|
|
30
|
+
return files
|
|
31
|
+
.map((file) => `
|
|
32
|
+
if (${idVariable}.replaceAll(${JSON.stringify(sep)}, ${JSON.stringify(posix.sep)}).endsWith(${JSON.stringify(normalizePath(file))})) {
|
|
33
|
+
return require(${JSON.stringify(join(serverDir, file))});
|
|
34
|
+
}`)
|
|
35
|
+
.join("\n");
|
|
36
|
+
}
|
|
37
|
+
export function inlineDynamicRequires(updater, buildOpts) {
|
|
38
|
+
updater.updateContent("inline-node-module-loader", {
|
|
39
|
+
filter: getCrossPlatformPathRegex(String.raw `/next/dist/server/lib/module-loader/node-module-loader\.js$`, { escape: false }),
|
|
40
|
+
contentFilter: /class NodeModuleLoader {/,
|
|
41
|
+
}, async ({ contents }) => patchCode(contents, await getNodeModuleLoaderRule(buildOpts)));
|
|
42
|
+
updater.updateContent("inline-require-page", {
|
|
43
|
+
filter: getCrossPlatformPathRegex(String.raw `/next/dist/server/require\.js$`, { escape: false }),
|
|
44
|
+
contentFilter: /function requirePage\(/,
|
|
45
|
+
}, async ({ contents }) => patchCode(contents, await getRequirePageRule(buildOpts)));
|
|
46
|
+
return { name: "inline-dynamic-requires", setup() { } };
|
|
47
|
+
}
|
|
48
|
+
async function getNodeModuleLoaderRule(buildOpts) {
|
|
49
|
+
const serverDir = getServerDir(buildOpts);
|
|
50
|
+
const manifests = await getPagesManifests(serverDir);
|
|
51
|
+
const files = manifests.filter((file) => file.endsWith(".js"));
|
|
52
|
+
return `
|
|
53
|
+
rule:
|
|
54
|
+
kind: method_definition
|
|
55
|
+
all:
|
|
56
|
+
- has:
|
|
57
|
+
field: name
|
|
58
|
+
regex: ^load$
|
|
59
|
+
- has:
|
|
60
|
+
field: parameters
|
|
61
|
+
has:
|
|
62
|
+
kind: required_parameter
|
|
63
|
+
pattern: $ID
|
|
64
|
+
inside:
|
|
65
|
+
stopBy:
|
|
66
|
+
kind: class_declaration
|
|
67
|
+
kind: class_declaration
|
|
68
|
+
has:
|
|
69
|
+
field: name
|
|
70
|
+
regex: ^NodeModuleLoader$
|
|
71
|
+
fix: |
|
|
72
|
+
async load($ID) {
|
|
73
|
+
${getRequires("$ID", files, serverDir)}
|
|
74
|
+
}`;
|
|
75
|
+
}
|
|
76
|
+
async function getRequirePageRule(buildOpts) {
|
|
77
|
+
const serverDir = getServerDir(buildOpts);
|
|
78
|
+
const pagesManifests = await getPagesManifests(serverDir);
|
|
79
|
+
const appPathsManifests = await getAppPathsManifests(serverDir);
|
|
80
|
+
const manifests = pagesManifests.concat(appPathsManifests);
|
|
81
|
+
const htmlFiles = manifests.filter((file) => file.endsWith(".html"));
|
|
82
|
+
const jsFiles = manifests.filter((file) => file.endsWith(".js"));
|
|
83
|
+
return {
|
|
84
|
+
rule: {
|
|
85
|
+
pattern: `
|
|
86
|
+
function requirePage($PAGE, $DIST_DIR, $IS_APP_PATH) {
|
|
87
|
+
const $_ = getPagePath($$$ARGS);
|
|
88
|
+
$$$_BODY
|
|
89
|
+
}`,
|
|
90
|
+
}, // Inline fs access and dynamic require that are not supported by workerd.
|
|
91
|
+
fix: `
|
|
92
|
+
function requirePage($PAGE, $DIST_DIR, $IS_APP_PATH) {
|
|
93
|
+
const pagePath = getPagePath($$$ARGS).replaceAll(${JSON.stringify(sep)}, ${JSON.stringify(posix.sep)});
|
|
94
|
+
|
|
95
|
+
// html
|
|
96
|
+
${(await Promise.all(htmlFiles.map(async (file) => `if (pagePath.endsWith(${JSON.stringify(normalizePath(file))})) {
|
|
97
|
+
return ${JSON.stringify(await readFile(join(serverDir, file), "utf-8"))};
|
|
98
|
+
}`))).join("\n")}
|
|
99
|
+
// js
|
|
100
|
+
process.env.__NEXT_PRIVATE_RUNTIME_TYPE = $IS_APP_PATH ? 'app' : 'pages';
|
|
101
|
+
try {
|
|
102
|
+
${getRequires("pagePath", jsFiles, serverDir)}
|
|
103
|
+
} finally {
|
|
104
|
+
process.env.__NEXT_PRIVATE_RUNTIME_TYPE = '';
|
|
105
|
+
}
|
|
106
|
+
}`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Inline `evalManifest` as it relies on `readFileSync` and `runInNewContext`
|
|
3
3
|
* that are not supported by workerd.
|
|
4
4
|
*/
|
|
5
|
-
import { join, relative } from "node:path";
|
|
5
|
+
import { join, posix, relative, sep } from "node:path";
|
|
6
6
|
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
7
7
|
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
|
|
8
8
|
import { glob } from "glob";
|
|
@@ -46,8 +46,7 @@ function evalManifest($PATH, $$$ARGS) {
|
|
|
46
46
|
},
|
|
47
47
|
fix: `
|
|
48
48
|
function evalManifest($PATH, $$$ARGS) {
|
|
49
|
-
|
|
50
|
-
$PATH = platform === 'win32' ? $PATH.replaceAll('\\\\', '/') : $PATH;
|
|
49
|
+
$PATH = $PATH.replaceAll(${JSON.stringify(sep)}, ${JSON.stringify(posix.sep)});
|
|
51
50
|
${returnManifests}
|
|
52
51
|
throw new Error(\`Unexpected evalManifest(\${$PATH}) call!\`);
|
|
53
52
|
}`,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Inline `findDir` as it relies on `existsSync` which is not supported by workerd.
|
|
3
3
|
*/
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
|
-
import { join } from "node:path";
|
|
5
|
+
import { join, posix, sep } from "node:path";
|
|
6
6
|
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
7
7
|
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
|
|
8
8
|
import { patchCode } from "../ast/util.js";
|
|
@@ -22,8 +22,7 @@ rule:
|
|
|
22
22
|
pattern: function findDir($DIR, $NAME) { $$$_ }
|
|
23
23
|
fix: |-
|
|
24
24
|
function findDir($DIR, $NAME) {
|
|
25
|
-
|
|
26
|
-
$DIR = platform === 'win32' ? $DIR.replaceAll('\\\\', '/') : $DIR;
|
|
25
|
+
$DIR = $DIR.replaceAll(${JSON.stringify(sep)}, ${JSON.stringify(posix.sep)});
|
|
27
26
|
if ($DIR.endsWith(".next/server")) {
|
|
28
27
|
if ($NAME === "app") {
|
|
29
28
|
return ${appExists};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Inline `loadManifest` as it relies on `readFileSync` that is not supported by workerd.
|
|
3
3
|
*/
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
|
-
import { join, relative } from "node:path";
|
|
5
|
+
import { join, posix, relative, sep } from "node:path";
|
|
6
6
|
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
7
7
|
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
|
|
8
8
|
import { glob } from "glob";
|
|
@@ -33,8 +33,7 @@ function loadManifest($PATH, $$$ARGS) {
|
|
|
33
33
|
},
|
|
34
34
|
fix: `
|
|
35
35
|
function loadManifest($PATH, $$$ARGS) {
|
|
36
|
-
|
|
37
|
-
$PATH = platform === 'win32' ? $PATH.replaceAll('\\\\', '/') : $PATH;
|
|
36
|
+
$PATH = $PATH.replaceAll(${JSON.stringify(sep)}, ${JSON.stringify(posix.sep)});
|
|
38
37
|
${returnManifests}
|
|
39
38
|
throw new Error(\`Unexpected loadManifest(\${$PATH}) call!\`);
|
|
40
39
|
}`,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ContentUpdater } from "./content-updater.js";
|
|
2
|
+
export declare const abortControllerRule = "\nrule:\n all: \n - kind: lexical_declaration\n pattern: let $VAR = new AbortController\n - precedes:\n kind: function_declaration\n stopBy: end\n has:\n kind: statement_block\n has:\n kind: try_statement\n has:\n kind: catch_clause\n has:\n kind: statement_block\n has: \n kind: return_statement\n all: \n - has: \n stopBy: end\n kind: member_expression\n pattern: $VAR.signal.aborted\n - has:\n stopBy: end\n kind: call_expression\n regex: console.error\\(\"Failed to fetch RSC payload for\n \nfix:\n 'let $VAR = {signal:{aborted: false}};'\n";
|
|
3
|
+
export declare const nextMinimalRule = "\nrule:\n kind: member_expression\n pattern: process.env.NEXT_MINIMAL\n any: \n - inside:\n kind: parenthesized_expression\n stopBy: end\n inside:\n kind: if_statement\n any:\n - inside:\n kind: statement_block\n inside:\n kind: method_definition\n any:\n - has: {kind: property_identifier, field: name, regex: runEdgeFunction}\n - has: {kind: property_identifier, field: name, regex: runMiddleware}\n - has: {kind: property_identifier, field: name, regex: imageOptimizer}\n - has:\n kind: statement_block\n has:\n kind: expression_statement\n pattern: res.statusCode = 400;\nfix:\n 'true' \n";
|
|
4
|
+
export declare function patchNextMinimal(updater: ContentUpdater): {
|
|
5
|
+
name: string;
|
|
6
|
+
setup(): void;
|
|
7
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { patchCode } from "../ast/util.js";
|
|
2
|
+
// We try to be as specific as possible to avoid patching the wrong thing here
|
|
3
|
+
// It seems that there is a bug in the worker runtime. When the AbortController is created outside of the request context it throws an error (not sure if it's expected or not) except in this case. https://github.com/cloudflare/workerd/issues/3657
|
|
4
|
+
// It fails while requiring the `app-page.runtime.prod.js` file, but instead of throwing an error, it just return an empty object for the `require('app-page.runtime.prod.js')` call which makes every request to an app router page fail.
|
|
5
|
+
// If it's a bug in workerd and it's not expected to throw an error, we can remove this patch.
|
|
6
|
+
export const abortControllerRule = `
|
|
7
|
+
rule:
|
|
8
|
+
all:
|
|
9
|
+
- kind: lexical_declaration
|
|
10
|
+
pattern: let $VAR = new AbortController
|
|
11
|
+
- precedes:
|
|
12
|
+
kind: function_declaration
|
|
13
|
+
stopBy: end
|
|
14
|
+
has:
|
|
15
|
+
kind: statement_block
|
|
16
|
+
has:
|
|
17
|
+
kind: try_statement
|
|
18
|
+
has:
|
|
19
|
+
kind: catch_clause
|
|
20
|
+
has:
|
|
21
|
+
kind: statement_block
|
|
22
|
+
has:
|
|
23
|
+
kind: return_statement
|
|
24
|
+
all:
|
|
25
|
+
- has:
|
|
26
|
+
stopBy: end
|
|
27
|
+
kind: member_expression
|
|
28
|
+
pattern: $VAR.signal.aborted
|
|
29
|
+
- has:
|
|
30
|
+
stopBy: end
|
|
31
|
+
kind: call_expression
|
|
32
|
+
regex: console.error\\("Failed to fetch RSC payload for
|
|
33
|
+
|
|
34
|
+
fix:
|
|
35
|
+
'let $VAR = {signal:{aborted: false}};'
|
|
36
|
+
`;
|
|
37
|
+
// This rule is used instead of defining `process.env.NEXT_MINIMAL` in the `esbuild config.
|
|
38
|
+
// Do we want to entirely replace these functions to reduce the bundle size?
|
|
39
|
+
// In next `renderHTML` is used as a fallback in case of errors, but in minimal mode it just throws the error and the responsability of handling it is on the infra.
|
|
40
|
+
export const nextMinimalRule = `
|
|
41
|
+
rule:
|
|
42
|
+
kind: member_expression
|
|
43
|
+
pattern: process.env.NEXT_MINIMAL
|
|
44
|
+
any:
|
|
45
|
+
- inside:
|
|
46
|
+
kind: parenthesized_expression
|
|
47
|
+
stopBy: end
|
|
48
|
+
inside:
|
|
49
|
+
kind: if_statement
|
|
50
|
+
any:
|
|
51
|
+
- inside:
|
|
52
|
+
kind: statement_block
|
|
53
|
+
inside:
|
|
54
|
+
kind: method_definition
|
|
55
|
+
any:
|
|
56
|
+
- has: {kind: property_identifier, field: name, regex: runEdgeFunction}
|
|
57
|
+
- has: {kind: property_identifier, field: name, regex: runMiddleware}
|
|
58
|
+
- has: {kind: property_identifier, field: name, regex: imageOptimizer}
|
|
59
|
+
- has:
|
|
60
|
+
kind: statement_block
|
|
61
|
+
has:
|
|
62
|
+
kind: expression_statement
|
|
63
|
+
pattern: res.statusCode = 400;
|
|
64
|
+
fix:
|
|
65
|
+
'true'
|
|
66
|
+
`;
|
|
67
|
+
export function patchNextMinimal(updater) {
|
|
68
|
+
updater.updateContent("patch-abortController-next15.2", { filter: /app-page(-experimental)?\.runtime\.prod\.js$/, contentFilter: /new AbortController/ }, async ({ contents }) => {
|
|
69
|
+
return patchCode(contents, abortControllerRule);
|
|
70
|
+
});
|
|
71
|
+
updater.updateContent("patch-next-minimal", { filter: /next-server\.(js)$/, contentFilter: /.*/ }, async ({ contents }) => {
|
|
72
|
+
return patchCode(contents, nextMinimalRule);
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
name: "patch-abortController",
|
|
76
|
+
setup() { },
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { patchCode } from "../ast/util";
|
|
3
|
+
import { abortControllerRule } from "./next-minimal";
|
|
4
|
+
const appPageRuntimeProdJs = `let p = new AbortController;
|
|
5
|
+
async function h(e3, t3) {
|
|
6
|
+
let { flightRouterState: r3, nextUrl: a2, prefetchKind: i2 } = t3, u2 = { [n2.hY]: "1", [n2.B]: encodeURIComponent(JSON.stringify(r3)) };
|
|
7
|
+
i2 === o.ob.AUTO && (u2[n2._V] = "1"), a2 && (u2[n2.kO] = a2);
|
|
8
|
+
try {
|
|
9
|
+
var c2;
|
|
10
|
+
let t4 = i2 ? i2 === o.ob.TEMPORARY ? "high" : "low" : "auto";
|
|
11
|
+
"export" === process.env.__NEXT_CONFIG_OUTPUT && ((e3 = new URL(e3)).pathname.endsWith("/") ? e3.pathname += "index.txt" : e3.pathname += ".txt");
|
|
12
|
+
let r4 = await m(e3, u2, t4, p.signal), a3 = d(r4.url), h2 = r4.redirected ? a3 : void 0, g = r4.headers.get("content-type") || "", v = !!(null == (c2 = r4.headers.get("vary")) ? void 0 : c2.includes(n2.kO)), b = !!r4.headers.get(n2.jc), S = r4.headers.get(n2.UK), _ = null !== S ? parseInt(S, 10) : -1, w = g.startsWith(n2.al);
|
|
13
|
+
if ("export" !== process.env.__NEXT_CONFIG_OUTPUT || w || (w = g.startsWith("text/plain")), !w || !r4.ok || !r4.body)
|
|
14
|
+
return e3.hash && (a3.hash = e3.hash), f(a3.toString());
|
|
15
|
+
let k = b ? function(e4) {
|
|
16
|
+
let t5 = e4.getReader();
|
|
17
|
+
return new ReadableStream({ async pull(e5) {
|
|
18
|
+
for (; ; ) {
|
|
19
|
+
let { done: r5, value: n3 } = await t5.read();
|
|
20
|
+
if (!r5) {
|
|
21
|
+
e5.enqueue(n3);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
} });
|
|
27
|
+
}(r4.body) : r4.body, E = await y(k);
|
|
28
|
+
if ((0, l.X)() !== E.b)
|
|
29
|
+
return f(r4.url);
|
|
30
|
+
return { flightData: (0, s.aj)(E.f), canonicalUrl: h2, couldBeIntercepted: v, prerendered: E.S, postponed: b, staleTime: _ };
|
|
31
|
+
} catch (t4) {
|
|
32
|
+
return p.signal.aborted || console.error("Failed to fetch RSC payload for " + e3 + ". Falling back to browser navigation.", t4), { flightData: e3.toString(), canonicalUrl: void 0, couldBeIntercepted: false, prerendered: false, postponed: false, staleTime: -1 };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
describe("Abort controller", () => {
|
|
37
|
+
test("minimal", () => {
|
|
38
|
+
expect(patchCode(appPageRuntimeProdJs, abortControllerRule)).toBe(`let p = {signal:{aborted: false}};
|
|
39
|
+
async function h(e3, t3) {
|
|
40
|
+
let { flightRouterState: r3, nextUrl: a2, prefetchKind: i2 } = t3, u2 = { [n2.hY]: "1", [n2.B]: encodeURIComponent(JSON.stringify(r3)) };
|
|
41
|
+
i2 === o.ob.AUTO && (u2[n2._V] = "1"), a2 && (u2[n2.kO] = a2);
|
|
42
|
+
try {
|
|
43
|
+
var c2;
|
|
44
|
+
let t4 = i2 ? i2 === o.ob.TEMPORARY ? "high" : "low" : "auto";
|
|
45
|
+
"export" === process.env.__NEXT_CONFIG_OUTPUT && ((e3 = new URL(e3)).pathname.endsWith("/") ? e3.pathname += "index.txt" : e3.pathname += ".txt");
|
|
46
|
+
let r4 = await m(e3, u2, t4, p.signal), a3 = d(r4.url), h2 = r4.redirected ? a3 : void 0, g = r4.headers.get("content-type") || "", v = !!(null == (c2 = r4.headers.get("vary")) ? void 0 : c2.includes(n2.kO)), b = !!r4.headers.get(n2.jc), S = r4.headers.get(n2.UK), _ = null !== S ? parseInt(S, 10) : -1, w = g.startsWith(n2.al);
|
|
47
|
+
if ("export" !== process.env.__NEXT_CONFIG_OUTPUT || w || (w = g.startsWith("text/plain")), !w || !r4.ok || !r4.body)
|
|
48
|
+
return e3.hash && (a3.hash = e3.hash), f(a3.toString());
|
|
49
|
+
let k = b ? function(e4) {
|
|
50
|
+
let t5 = e4.getReader();
|
|
51
|
+
return new ReadableStream({ async pull(e5) {
|
|
52
|
+
for (; ; ) {
|
|
53
|
+
let { done: r5, value: n3 } = await t5.read();
|
|
54
|
+
if (!r5) {
|
|
55
|
+
e5.enqueue(n3);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
} });
|
|
61
|
+
}(r4.body) : r4.body, E = await y(k);
|
|
62
|
+
if ((0, l.X)() !== E.b)
|
|
63
|
+
return f(r4.url);
|
|
64
|
+
return { flightData: (0, s.aj)(E.f), canonicalUrl: h2, couldBeIntercepted: v, prerendered: E.S, postponed: b, staleTime: _ };
|
|
65
|
+
} catch (t4) {
|
|
66
|
+
return p.signal.aborted || console.error("Failed to fetch RSC payload for " + e3 + ". Falling back to browser navigation.", t4), { flightData: e3.toString(), canonicalUrl: void 0, couldBeIntercepted: false, prerendered: false, postponed: false, staleTime: -1 };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
`);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { NextConfig } from "@opennextjs/aws/types/next-types";
|
|
2
|
+
interface ExtendedNextConfig extends NextConfig {
|
|
3
|
+
experimental: {
|
|
4
|
+
ppr?: boolean;
|
|
5
|
+
taint?: boolean;
|
|
6
|
+
viewTransition?: boolean;
|
|
7
|
+
serverActions?: boolean;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export declare function needsExperimentalReact(nextConfig: ExtendedNextConfig): boolean;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Copied from https://github.com/vercel/next.js/blob/4518bc91641a0fd938664b781e12ae7c145f3396/packages/next/src/lib/needs-experimental-react.ts#L3-L6
|
|
2
|
+
export function needsExperimentalReact(nextConfig) {
|
|
3
|
+
const { ppr, taint, viewTransition } = nextConfig.experimental || {};
|
|
4
|
+
return Boolean(ppr || taint || viewTransition);
|
|
5
|
+
}
|
package/package.json
CHANGED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
4
|
-
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
|
|
5
|
-
import { normalizePath } from "../../utils/normalize-path.js";
|
|
6
|
-
import { patchCode } from "../ast/util.js";
|
|
7
|
-
export function inlineRequirePage(updater, buildOpts) {
|
|
8
|
-
return updater.updateContent("inline-require-page", {
|
|
9
|
-
filter: getCrossPlatformPathRegex(String.raw `/next/dist/server/require\.js$`, { escape: false }),
|
|
10
|
-
contentFilter: /function requirePage\(/,
|
|
11
|
-
}, async ({ contents }) => patchCode(contents, await getRule(buildOpts)));
|
|
12
|
-
}
|
|
13
|
-
async function getRule(buildOpts) {
|
|
14
|
-
const { outputDir } = buildOpts;
|
|
15
|
-
const serverDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
|
|
16
|
-
const pagesManifestFile = join(serverDir, "pages-manifest.json");
|
|
17
|
-
const appPathsManifestFile = join(serverDir, "app-paths-manifest.json");
|
|
18
|
-
let pagesManifests = [];
|
|
19
|
-
try {
|
|
20
|
-
pagesManifests = Object.values(JSON.parse(await readFile(pagesManifestFile, "utf-8")));
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
// The file does not exists
|
|
24
|
-
pagesManifests = [];
|
|
25
|
-
}
|
|
26
|
-
let appPathsManifests;
|
|
27
|
-
try {
|
|
28
|
-
appPathsManifests = Object.values(JSON.parse(await readFile(appPathsManifestFile, "utf-8")));
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
// The file does not exists
|
|
32
|
-
appPathsManifests = [];
|
|
33
|
-
}
|
|
34
|
-
const manifests = pagesManifests.concat(appPathsManifests).map((path) => normalizePath(path));
|
|
35
|
-
const htmlFiles = manifests.filter((file) => file.endsWith(".html"));
|
|
36
|
-
const jsFiles = manifests.filter((file) => file.endsWith(".js"));
|
|
37
|
-
// Inline fs access and dynamic require that are not supported by workerd.
|
|
38
|
-
const fnBody = `
|
|
39
|
-
// html
|
|
40
|
-
${(await Promise.all(htmlFiles.map(async (file) => `if (pagePath.endsWith("${file}")) {
|
|
41
|
-
return ${JSON.stringify(await readFile(join(serverDir, file), "utf-8"))};
|
|
42
|
-
}`))).join("\n")}
|
|
43
|
-
// js
|
|
44
|
-
process.env.__NEXT_PRIVATE_RUNTIME_TYPE = isAppPath ? 'app' : 'pages';
|
|
45
|
-
try {
|
|
46
|
-
${jsFiles
|
|
47
|
-
.map((file) => `if (pagePath.endsWith("${file}")) {
|
|
48
|
-
return require(${JSON.stringify(join(serverDir, file))});
|
|
49
|
-
}`)
|
|
50
|
-
.join("\n")}
|
|
51
|
-
} finally {
|
|
52
|
-
process.env.__NEXT_PRIVATE_RUNTIME_TYPE = '';
|
|
53
|
-
}
|
|
54
|
-
`;
|
|
55
|
-
return {
|
|
56
|
-
rule: {
|
|
57
|
-
pattern: `
|
|
58
|
-
function requirePage($PAGE, $DIST_DIR, $IS_APP_PATH) {
|
|
59
|
-
const $_ = getPagePath($$$ARGS);
|
|
60
|
-
$$$_BODY
|
|
61
|
-
}`,
|
|
62
|
-
},
|
|
63
|
-
fix: `
|
|
64
|
-
function requirePage($PAGE, $DIST_DIR, $IS_APP_PATH) {
|
|
65
|
-
const { platform } = require('process');
|
|
66
|
-
const pagePath = platform === 'win32' ? getPagePath($$$ARGS).replaceAll('\\\\', '/') : getPagePath($$$ARGS);
|
|
67
|
-
${fnBody}
|
|
68
|
-
}`,
|
|
69
|
-
};
|
|
70
|
-
}
|