@opennextjs/cloudflare 1.20.1 → 1.20.3
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/build.js +7 -4
- package/dist/cli/build/bundle-server.js +1 -1
- package/dist/cli/build/open-next/bundle-node-middleware.d.ts +50 -0
- package/dist/cli/build/open-next/bundle-node-middleware.js +274 -0
- package/dist/cli/build/patches/ast/webpack-runtime.d.ts +1 -2
- package/dist/cli/build/patches/ast/webpack-runtime.js +9 -9
- package/dist/cli/build/patches/plugins/instrumentation.d.ts +16 -1
- package/dist/cli/build/patches/plugins/instrumentation.js +15 -2
- package/dist/cli/build/patches/plugins/turbopack.d.ts +57 -0
- package/dist/cli/build/patches/plugins/turbopack.js +122 -11
- package/dist/cli/utils/create-wrangler-config.js +1 -1
- package/dist/cli/utils/normalize-path.js +1 -2
- package/package.json +5 -5
package/dist/cli/build/build.js
CHANGED
|
@@ -8,6 +8,7 @@ import { printHeader } from "@opennextjs/aws/build/utils.js";
|
|
|
8
8
|
import logger from "@opennextjs/aws/logger.js";
|
|
9
9
|
import { ensureNextjsVersionSupported } from "../utils/nextjs-support.js";
|
|
10
10
|
import { bundleServer } from "./bundle-server.js";
|
|
11
|
+
import { bundleNodeMiddleware } from "./open-next/bundle-node-middleware.js";
|
|
11
12
|
import { compileCacheAssetsManifestSqlFile } from "./open-next/compile-cache-assets-manifest.js";
|
|
12
13
|
import { compileEnvFiles } from "./open-next/compile-env-files.js";
|
|
13
14
|
import { compileImages } from "./open-next/compile-images.js";
|
|
@@ -62,10 +63,9 @@ export async function build(options, config, projectOpts, wranglerConfig, allowU
|
|
|
62
63
|
setStandaloneBuildMode(options);
|
|
63
64
|
buildNextjsApp(options);
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
logger.
|
|
68
|
-
process.exit(1);
|
|
66
|
+
const hasNodeMiddleware = useNodeMiddleware(options);
|
|
67
|
+
if (hasNodeMiddleware) {
|
|
68
|
+
logger.warn("Node.js middleware support is experimental in cloudflare, and not officially maintained by OpenNext maintainers. Use at your own risk.");
|
|
69
69
|
}
|
|
70
70
|
// Generate deployable bundle
|
|
71
71
|
printHeader("Generating bundle");
|
|
@@ -77,6 +77,9 @@ export async function build(options, config, projectOpts, wranglerConfig, allowU
|
|
|
77
77
|
await compileSkewProtection(options, config);
|
|
78
78
|
// Compile middleware
|
|
79
79
|
await createMiddleware(options, { forceOnlyBuildOnce: true });
|
|
80
|
+
if (hasNodeMiddleware) {
|
|
81
|
+
await bundleNodeMiddleware(options);
|
|
82
|
+
}
|
|
80
83
|
createStaticAssets(options, { useBasePath: true });
|
|
81
84
|
if (config.dangerous?.disableIncrementalCache !== true) {
|
|
82
85
|
const { useTagCache, metaFiles } = createCacheAssets(options);
|
|
@@ -52,7 +52,7 @@ export async function bundleServer(buildOpts, projectOpts) {
|
|
|
52
52
|
const nextConfig = JSON.parse(fs.readFileSync(serverFiles, "utf-8")).config;
|
|
53
53
|
const useTurbopack = buildHelper.getBundlerRuntime(buildOpts) === "turbopack";
|
|
54
54
|
console.log(`\x1b[35m⚙️ Bundling the OpenNext server...\n\x1b[0m`);
|
|
55
|
-
await patchWebpackRuntime(
|
|
55
|
+
await patchWebpackRuntime(path.join(dotNextPath, "server"));
|
|
56
56
|
const useOg = patchVercelOgLibrary(buildOpts);
|
|
57
57
|
const outputPath = path.join(outputDir, "server-functions", "default");
|
|
58
58
|
const packagePath = getPackagePath(buildOpts);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundles the Node.js middleware (`proxy.ts` / `middleware.ts` with the `nodejs` runtime)
|
|
3
|
+
* into a Workers compatible `middleware/handler.mjs`.
|
|
4
|
+
*
|
|
5
|
+
* NOTE: Running Next.js Node.js middleware on workerd is experimental and is not supported
|
|
6
|
+
* by the OpenNext maintainers. It re-bundles the middleware compiled by Next.js, which is an
|
|
7
|
+
* internal output that can change between Next.js versions.
|
|
8
|
+
*
|
|
9
|
+
* `@opennextjs/aws` bundles the external middleware for a Node.js server:
|
|
10
|
+
* the OpenNext config is read from the filesystem at runtime and the middleware compiled
|
|
11
|
+
* by Next.js is loaded with `await import("./.next/server/middleware.js")`.
|
|
12
|
+
*
|
|
13
|
+
* workerd can not access the filesystem nor load modules at runtime, so the handler
|
|
14
|
+
* built by `@opennextjs/aws` is replaced with a fully self-contained bundle:
|
|
15
|
+
*
|
|
16
|
+
* - the config manifests are inlined by `openNextEdgePlugins` (as for the edge middleware)
|
|
17
|
+
* - the middleware compiled by Next.js is statically bundled from the traced files that
|
|
18
|
+
* `@opennextjs/aws` copies to `middleware/<package path>/.next/server/middleware.js`
|
|
19
|
+
*/
|
|
20
|
+
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
21
|
+
import { type Plugin } from "esbuild";
|
|
22
|
+
/**
|
|
23
|
+
* Resolves the middleware compiled by Next.js to the copy created by `copyTracedFiles`.
|
|
24
|
+
*
|
|
25
|
+
* `@opennextjs/aws`'s `nodeMiddlewareHandler` loads the middleware with a dynamic
|
|
26
|
+
* `await import("./.next/server/middleware.js")` that nothing on the aws side resolves (it relies
|
|
27
|
+
* on the adapter bundling it), so this resolves that specifier to the traced copy.
|
|
28
|
+
*/
|
|
29
|
+
export declare function setCompiledMiddlewarePlugin(compiledMiddlewarePath: string): Plugin;
|
|
30
|
+
/**
|
|
31
|
+
* Makes the Node.js builtins used by the bundled code (i.e. `require("crypto")` or
|
|
32
|
+
* `import from "node:crypto"`) resolve to the modules workerd provides via `nodejs_compat`.
|
|
33
|
+
*
|
|
34
|
+
* `require` calls are converted into a virtual CommonJS module re-exporting the builtin.
|
|
35
|
+
* The virtual module has to stay CommonJS - esbuild classifies it as such because it assigns to
|
|
36
|
+
* `module.exports` and uses no `export` keyword - so that `require("crypto")` receives the module
|
|
37
|
+
* workerd provides rather than an esbuild `__toCommonJS` wrapper built from its named exports,
|
|
38
|
+
* which would drop whatever the named exports do not expose and add a synthetic `__esModule`.
|
|
39
|
+
*
|
|
40
|
+
* The conversion is kept in sync with `handleRequireCallsToNodeJSBuiltins` in wrangler's
|
|
41
|
+
* `hybrid-nodejs-compat` esbuild plugin, which is the source of truth:
|
|
42
|
+
* https://github.com/cloudflare/workers-sdk/blob/c457bfc6b5a575586354f5b0ad7a1100eff915fe/packages/wrangler/src/deployment-bundle/esbuild-plugins/hybrid-nodejs-compat.ts#L102-L133
|
|
43
|
+
*
|
|
44
|
+
* It differs on a single intentional point: the builtin is imported as a namespace and
|
|
45
|
+
* `mod.default ?? mod` is used rather than a default import, so that a builtin without a `default`
|
|
46
|
+
* export can not fail to link in workerd. wrangler applies the same fallback to its unenv aliases
|
|
47
|
+
* in `handleUnenvAliasedPackages`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function nodeBuiltinsPlugin(): Plugin;
|
|
50
|
+
export declare function bundleNodeMiddleware(options: BuildOptions): Promise<void>;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundles the Node.js middleware (`proxy.ts` / `middleware.ts` with the `nodejs` runtime)
|
|
3
|
+
* into a Workers compatible `middleware/handler.mjs`.
|
|
4
|
+
*
|
|
5
|
+
* NOTE: Running Next.js Node.js middleware on workerd is experimental and is not supported
|
|
6
|
+
* by the OpenNext maintainers. It re-bundles the middleware compiled by Next.js, which is an
|
|
7
|
+
* internal output that can change between Next.js versions.
|
|
8
|
+
*
|
|
9
|
+
* `@opennextjs/aws` bundles the external middleware for a Node.js server:
|
|
10
|
+
* the OpenNext config is read from the filesystem at runtime and the middleware compiled
|
|
11
|
+
* by Next.js is loaded with `await import("./.next/server/middleware.js")`.
|
|
12
|
+
*
|
|
13
|
+
* workerd can not access the filesystem nor load modules at runtime, so the handler
|
|
14
|
+
* built by `@opennextjs/aws` is replaced with a fully self-contained bundle:
|
|
15
|
+
*
|
|
16
|
+
* - the config manifests are inlined by `openNextEdgePlugins` (as for the edge middleware)
|
|
17
|
+
* - the middleware compiled by Next.js is statically bundled from the traced files that
|
|
18
|
+
* `@opennextjs/aws` copies to `middleware/<package path>/.next/server/middleware.js`
|
|
19
|
+
*/
|
|
20
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
21
|
+
import { builtinModules, isBuiltin } from "node:module";
|
|
22
|
+
import path from "node:path";
|
|
23
|
+
import { getBundlerRuntime, getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
24
|
+
import logger from "@opennextjs/aws/logger.js";
|
|
25
|
+
import { ContentUpdater } from "@opennextjs/aws/plugins/content-updater.js";
|
|
26
|
+
import { openNextEdgePlugins } from "@opennextjs/aws/plugins/edge.js";
|
|
27
|
+
import { openNextExternalMiddlewarePlugin } from "@opennextjs/aws/plugins/externalMiddleware.js";
|
|
28
|
+
import { openNextReplacementPlugin } from "@opennextjs/aws/plugins/replacement.js";
|
|
29
|
+
import { openNextResolvePlugin } from "@opennextjs/aws/plugins/resolve.js";
|
|
30
|
+
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
|
|
31
|
+
import { build } from "esbuild";
|
|
32
|
+
import { glob } from "glob";
|
|
33
|
+
import { normalizePath } from "../../utils/normalize-path.js";
|
|
34
|
+
import { patchWebpackRuntime } from "../patches/ast/webpack-runtime.js";
|
|
35
|
+
import { patchInstrumentation } from "../patches/plugins/instrumentation.js";
|
|
36
|
+
import { patchTurbopackRuntimeCode, patchTurbopackWasmChunkCode } from "../patches/plugins/turbopack.js";
|
|
37
|
+
import { setWranglerExternal } from "../patches/plugins/wrangler-external.js";
|
|
38
|
+
/**
|
|
39
|
+
* Inlines the chunks of the middleware compiled by Next.js.
|
|
40
|
+
*
|
|
41
|
+
* Both the webpack and the Turbopack runtimes resolve the chunks they need at runtime,
|
|
42
|
+
* which workerd does not support. The same patches as for the server are used to inline them.
|
|
43
|
+
*
|
|
44
|
+
* @param options Build options.
|
|
45
|
+
* @param dotNextServerDir The `.next/server` directory of the middleware output.
|
|
46
|
+
*/
|
|
47
|
+
async function inlineMiddlewareChunks(options, dotNextServerDir) {
|
|
48
|
+
if (getBundlerRuntime(options) !== "turbopack") {
|
|
49
|
+
await patchWebpackRuntime(dotNextServerDir);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const runtimePath = path.join(dotNextServerDir, "chunks/[turbopack]_runtime.js");
|
|
53
|
+
if (!existsSync(runtimePath)) {
|
|
54
|
+
throw new Error(`Turbopack runtime not found at ${runtimePath}`);
|
|
55
|
+
}
|
|
56
|
+
// The Turbopack runtime resolves the chunks relative to the `.next` directory.
|
|
57
|
+
// `.wasm` chunks are needed too: they are inlined as static imports by `loadWasmChunk`.
|
|
58
|
+
const tracedFiles = await glob(path.join(dotNextServerDir, "**/*.{js,wasm}"), {
|
|
59
|
+
windowsPathsNoEscape: true,
|
|
60
|
+
});
|
|
61
|
+
writeFileSync(runtimePath, patchTurbopackRuntimeCode({
|
|
62
|
+
code: readFileSync(runtimePath, "utf-8"),
|
|
63
|
+
filePath: normalizePath(runtimePath),
|
|
64
|
+
tracedFiles,
|
|
65
|
+
}));
|
|
66
|
+
// Since Next.js 16.3 the wasm helpers are emitted in the chunks rather than in the runtime.
|
|
67
|
+
for (const chunkPath of tracedFiles) {
|
|
68
|
+
if (!chunkPath.endsWith(".js") || normalizePath(chunkPath) === normalizePath(runtimePath)) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const code = readFileSync(chunkPath, "utf-8");
|
|
72
|
+
const patched = patchTurbopackWasmChunkCode({ code, tracedFiles });
|
|
73
|
+
if (patched !== code) {
|
|
74
|
+
writeFileSync(chunkPath, patched);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Resolves the middleware compiled by Next.js to the copy created by `copyTracedFiles`.
|
|
80
|
+
*
|
|
81
|
+
* `@opennextjs/aws`'s `nodeMiddlewareHandler` loads the middleware with a dynamic
|
|
82
|
+
* `await import("./.next/server/middleware.js")` that nothing on the aws side resolves (it relies
|
|
83
|
+
* on the adapter bundling it), so this resolves that specifier to the traced copy.
|
|
84
|
+
*/
|
|
85
|
+
export function setCompiledMiddlewarePlugin(compiledMiddlewarePath) {
|
|
86
|
+
return {
|
|
87
|
+
name: "compiled-middleware",
|
|
88
|
+
setup(build) {
|
|
89
|
+
build.onResolve({ filter: getCrossPlatformPathRegex("./.next/server/middleware.js") }, () => ({
|
|
90
|
+
path: compiledMiddlewarePath,
|
|
91
|
+
}));
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Makes the Node.js builtins used by the bundled code (i.e. `require("crypto")` or
|
|
97
|
+
* `import from "node:crypto"`) resolve to the modules workerd provides via `nodejs_compat`.
|
|
98
|
+
*
|
|
99
|
+
* `require` calls are converted into a virtual CommonJS module re-exporting the builtin.
|
|
100
|
+
* The virtual module has to stay CommonJS - esbuild classifies it as such because it assigns to
|
|
101
|
+
* `module.exports` and uses no `export` keyword - so that `require("crypto")` receives the module
|
|
102
|
+
* workerd provides rather than an esbuild `__toCommonJS` wrapper built from its named exports,
|
|
103
|
+
* which would drop whatever the named exports do not expose and add a synthetic `__esModule`.
|
|
104
|
+
*
|
|
105
|
+
* The conversion is kept in sync with `handleRequireCallsToNodeJSBuiltins` in wrangler's
|
|
106
|
+
* `hybrid-nodejs-compat` esbuild plugin, which is the source of truth:
|
|
107
|
+
* https://github.com/cloudflare/workers-sdk/blob/c457bfc6b5a575586354f5b0ad7a1100eff915fe/packages/wrangler/src/deployment-bundle/esbuild-plugins/hybrid-nodejs-compat.ts#L102-L133
|
|
108
|
+
*
|
|
109
|
+
* It differs on a single intentional point: the builtin is imported as a namespace and
|
|
110
|
+
* `mod.default ?? mod` is used rather than a default import, so that a builtin without a `default`
|
|
111
|
+
* export can not fail to link in workerd. wrangler applies the same fallback to its unenv aliases
|
|
112
|
+
* in `handleUnenvAliasedPackages`.
|
|
113
|
+
*/
|
|
114
|
+
export function nodeBuiltinsPlugin() {
|
|
115
|
+
const namespace = "node-builtins";
|
|
116
|
+
// Match only Node.js builtins so esbuild does not call back on every import:
|
|
117
|
+
// the `node:` prefixed form and the bare names (`crypto`, `fs`, ...).
|
|
118
|
+
const builtinsFilter = new RegExp(`^(node:|(${builtinModules.join("|")})$)`);
|
|
119
|
+
return {
|
|
120
|
+
name: namespace,
|
|
121
|
+
setup(build) {
|
|
122
|
+
build.onResolve({ filter: builtinsFilter }, ({ path: specifier, kind }) => {
|
|
123
|
+
if (!isBuiltin(specifier)) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
const prefixed = specifier.startsWith("node:") ? specifier : `node:${specifier}`;
|
|
127
|
+
return kind === "require-call" ? { path: prefixed, namespace } : { path: prefixed, external: true };
|
|
128
|
+
});
|
|
129
|
+
build.onLoad({ filter: /^node:/, namespace }, ({ path: builtin }) => ({
|
|
130
|
+
contents: `
|
|
131
|
+
import * as mod from "${builtin}";
|
|
132
|
+
module.exports = mod.default ?? mod;
|
|
133
|
+
`,
|
|
134
|
+
loader: "js",
|
|
135
|
+
}));
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export async function bundleNodeMiddleware(options) {
|
|
140
|
+
const { config, outputDir } = options;
|
|
141
|
+
const middlewareDir = path.join(outputDir, "middleware");
|
|
142
|
+
const dotNextServerDir = path.join(middlewareDir, getPackagePath(options), ".next/server");
|
|
143
|
+
const compiledMiddleware = path.join(dotNextServerDir, "middleware.js");
|
|
144
|
+
if (!existsSync(compiledMiddleware)) {
|
|
145
|
+
throw new Error(`Compiled Node.js middleware not found at ${compiledMiddleware}`);
|
|
146
|
+
}
|
|
147
|
+
// The bundler runtime resolves the chunks of the middleware at runtime, which workerd does
|
|
148
|
+
// not support. Inline the chunks so that they are statically bundled.
|
|
149
|
+
await inlineMiddlewareChunks(options, dotNextServerDir);
|
|
150
|
+
logger.info("Bundling Node.js middleware...");
|
|
151
|
+
const middlewareConfig = config.middleware?.external ? config.middleware : undefined;
|
|
152
|
+
const overrides = {
|
|
153
|
+
...middlewareConfig?.override,
|
|
154
|
+
originResolver: middlewareConfig?.originResolver,
|
|
155
|
+
};
|
|
156
|
+
function override(target) {
|
|
157
|
+
// String and lazy loaded overrides are supported, see `buildEdgeBundle`
|
|
158
|
+
return typeof overrides[target] === "string" || typeof overrides[target] === "function"
|
|
159
|
+
? overrides[target]
|
|
160
|
+
: undefined;
|
|
161
|
+
}
|
|
162
|
+
const includeCache = config.dangerous?.enableCacheInterception;
|
|
163
|
+
// `next/dist/server/lib/trace/tracer.js` requires `@opentelemetry/api`, an optional
|
|
164
|
+
// dependency that most apps do not install. On the edge runtime Next.js does not fall
|
|
165
|
+
// back to its compiled copy when the require throws, so alias to that copy - but only
|
|
166
|
+
// when the app has not installed the real package, otherwise the real one is used.
|
|
167
|
+
const hasOpentelemetry = existsSync(path.join(options.appBuildOutputPath, "node_modules", "@opentelemetry", "api"));
|
|
168
|
+
const updater = new ContentUpdater(options);
|
|
169
|
+
await build({
|
|
170
|
+
entryPoints: [path.join(options.openNextDistDir, "adapters", "middleware.js")],
|
|
171
|
+
outfile: path.join(middlewareDir, "handler.mjs"),
|
|
172
|
+
allowOverwrite: true,
|
|
173
|
+
bundle: true,
|
|
174
|
+
format: "esm",
|
|
175
|
+
target: "es2022",
|
|
176
|
+
platform: "neutral",
|
|
177
|
+
minify: options.minify,
|
|
178
|
+
sourcemap: options.debug ? "inline" : false,
|
|
179
|
+
sourcesContent: false,
|
|
180
|
+
treeShaking: true,
|
|
181
|
+
conditions: ["module"],
|
|
182
|
+
mainFields: ["module", "main"],
|
|
183
|
+
external: ["node:*", "./open-next.config.mjs"],
|
|
184
|
+
define: {
|
|
185
|
+
// The base of the middleware compiled by Next.js is runtime agnostic. "edge" selects its
|
|
186
|
+
// Web API code paths (which workerd supports) over the Node.js server paths (which it does
|
|
187
|
+
// not): it also skips `setup-node-env.external.js`, which patches read-only workerd globals.
|
|
188
|
+
// Node.js builtins used by the middleware are still provided by workerd via `nodejs_compat`.
|
|
189
|
+
"process.env.NEXT_RUNTIME": '"edge"',
|
|
190
|
+
"process.env.NODE_ENV": '"production"',
|
|
191
|
+
},
|
|
192
|
+
alias: {
|
|
193
|
+
// See `hasOpentelemetry` above.
|
|
194
|
+
...(hasOpentelemetry ? {} : { "@opentelemetry/api": "next/dist/compiled/@opentelemetry/api" }),
|
|
195
|
+
},
|
|
196
|
+
plugins: [
|
|
197
|
+
openNextResolvePlugin({
|
|
198
|
+
overrides: {
|
|
199
|
+
wrapper: override("wrapper") ?? "cloudflare-edge",
|
|
200
|
+
converter: override("converter") ?? "edge",
|
|
201
|
+
...(includeCache
|
|
202
|
+
? {
|
|
203
|
+
tagCache: override("tagCache"),
|
|
204
|
+
incrementalCache: override("incrementalCache"),
|
|
205
|
+
queue: override("queue"),
|
|
206
|
+
}
|
|
207
|
+
: {}),
|
|
208
|
+
originResolver: override("originResolver") ?? "pattern-env",
|
|
209
|
+
proxyExternalRequest: override("proxyExternalRequest") ?? "fetch",
|
|
210
|
+
},
|
|
211
|
+
fnName: "middleware",
|
|
212
|
+
}),
|
|
213
|
+
openNextReplacementPlugin({
|
|
214
|
+
name: "externalMiddlewareOverrides",
|
|
215
|
+
target: getCrossPlatformPathRegex("adapters/middleware.js"),
|
|
216
|
+
deletes: includeCache ? [] : ["includeCacheInMiddleware"],
|
|
217
|
+
}),
|
|
218
|
+
// Handle the middleware with the OpenNext Node.js middleware handler
|
|
219
|
+
openNextExternalMiddlewarePlugin(path.join(options.openNextDistDir, "core", "nodeMiddlewareHandler.js")),
|
|
220
|
+
setCompiledMiddlewarePlugin(compiledMiddleware),
|
|
221
|
+
// `.wasm` and `.bin` files are bundled by wrangler, not by this build
|
|
222
|
+
setWranglerExternal(),
|
|
223
|
+
// Must be registered before `openNextEdgePlugins` to handle `require("node:*")` calls
|
|
224
|
+
nodeBuiltinsPlugin(),
|
|
225
|
+
// Inline the config manifests
|
|
226
|
+
openNextEdgePlugins({
|
|
227
|
+
nextDir: path.join(options.appBuildOutputPath, ".next"),
|
|
228
|
+
isInCloudflare: true,
|
|
229
|
+
}),
|
|
230
|
+
// Next.js 16.3 registers the instrumentation hook from the middleware itself when the
|
|
231
|
+
// middleware does not run on the edge runtime, by dynamically requiring
|
|
232
|
+
// `.next/server/instrumentation.js` - which workerd does not support.
|
|
233
|
+
//
|
|
234
|
+
// The guard Next.js uses (`process.env.NEXT_RUNTIME !== "edge"`) is inlined to `"nodejs"`
|
|
235
|
+
// when Next.js compiles the middleware, so the `define` above can not eliminate the branch.
|
|
236
|
+
// The loader is stubbed out instead, which matches what the edge runtime does here: it has
|
|
237
|
+
// no instrumentation entry to register, and the server function - which shares the isolate -
|
|
238
|
+
// already registers the hook.
|
|
239
|
+
// See https://github.com/opennextjs/opennextjs-cloudflare/issues/1362
|
|
240
|
+
patchInstrumentation(updater, options, { loadInstrumentation: false }),
|
|
241
|
+
// Apply updater updates, must be the last plugin
|
|
242
|
+
updater.plugin,
|
|
243
|
+
],
|
|
244
|
+
banner: {
|
|
245
|
+
js: `
|
|
246
|
+
import { Buffer } from "node:buffer";
|
|
247
|
+
globalThis.Buffer = Buffer;
|
|
248
|
+
|
|
249
|
+
// Next.js' compiled middleware references \`AsyncLocalStorage\` as a global. workerd only
|
|
250
|
+
// exposes it via \`node:async_hooks\` (not as a global, even with \`nodejs_compat\`), so it is
|
|
251
|
+
// assigned here - as \`@opennextjs/aws\`'s edge middleware bundler does.
|
|
252
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
253
|
+
globalThis.AsyncLocalStorage = AsyncLocalStorage;
|
|
254
|
+
|
|
255
|
+
// Next.js sets \`__import_unsupported\` on \`globalThis\` with \`configurable: false\`.
|
|
256
|
+
// When the middleware and the server share a Worker, the second call would throw,
|
|
257
|
+
// so it is skipped when the property is already set. Otherwise it runs as usual.
|
|
258
|
+
// See https://github.com/vercel/next.js/blob/5b7833e3/packages/next/src/server/web/globals.ts#L94-L98
|
|
259
|
+
const defaultDefineProperty = Object.defineProperty;
|
|
260
|
+
Object.defineProperty = function (o, p, a) {
|
|
261
|
+
if (p === "__import_unsupported" && Boolean(globalThis.__import_unsupported)) {
|
|
262
|
+
// \`Object.defineProperty\` returns the object it was passed.
|
|
263
|
+
return o;
|
|
264
|
+
}
|
|
265
|
+
return defaultDefineProperty(o, p, a);
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
globalThis.openNextDebug = ${options.debug};
|
|
269
|
+
globalThis.openNextVersion = "${options.openNextVersion}";
|
|
270
|
+
globalThis.nextVersion = "${options.nextVersion}";
|
|
271
|
+
`,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
}
|
|
@@ -19,11 +19,10 @@
|
|
|
19
19
|
* For a single chunk:
|
|
20
20
|
* require("./chunks/CHUNK_ID.js");
|
|
21
21
|
*/
|
|
22
|
-
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
23
22
|
export declare function buildMultipleChunksRule(chunks: number[]): string;
|
|
24
23
|
export declare const singleChunkRule = "\nrule:\n pattern: ($CHUNK_ID, $_PROMISES) => { $$$ }\n inside: {pattern: $_.$_.require = $$$_, stopBy: end}\n all:\n - has: {pattern: $INSTALL(require(\"./chunks/\" + $$$)), stopBy: end}\n - has: {pattern: $SELF_ID == $CHUNK_ID, stopBy: end}\n - has: {pattern: \"$INSTALLED_CHUNK[$CHUNK_ID] = 1\", stopBy: end}\nfix: |\n ($CHUNK_ID, _) => {\n if (!$INSTALLED_CHUNK[$CHUNK_ID]) {\n try {\n $INSTALL(require(\"./chunks/$SELF_ID.js\"));\n } catch {}\n }\n }\n";
|
|
25
24
|
/**
|
|
26
25
|
* Fixes the webpack-runtime.js and webpack-api-runtime.js files by inlining
|
|
27
26
|
* the webpack dynamic requires.
|
|
28
27
|
*/
|
|
29
|
-
export declare function patchWebpackRuntime(
|
|
28
|
+
export declare function patchWebpackRuntime(dotNextServerDir: string): Promise<void>;
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
23
23
|
import { join } from "node:path";
|
|
24
|
-
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
25
24
|
import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
|
|
26
25
|
// Inline the code when there are multiple chunks
|
|
27
26
|
export function buildMultipleChunksRule(chunks) {
|
|
@@ -68,15 +67,16 @@ fix: |
|
|
|
68
67
|
* Fixes the webpack-runtime.js and webpack-api-runtime.js files by inlining
|
|
69
68
|
* the webpack dynamic requires.
|
|
70
69
|
*/
|
|
71
|
-
export async function patchWebpackRuntime(
|
|
72
|
-
const { outputDir } = buildOpts;
|
|
73
|
-
const dotNextServerDir = join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next/server");
|
|
70
|
+
export async function patchWebpackRuntime(dotNextServerDir) {
|
|
74
71
|
// Look for all the chunks.
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
const chunksDir = join(dotNextServerDir, "chunks");
|
|
73
|
+
const chunks = existsSync(chunksDir)
|
|
74
|
+
? readdirSync(chunksDir)
|
|
75
|
+
.filter((chunk) => /^\d+\.js$/.test(chunk))
|
|
76
|
+
.map((chunk) => {
|
|
77
|
+
return Number(chunk.replace(/\.js$/, ""));
|
|
78
|
+
})
|
|
79
|
+
: [];
|
|
80
80
|
patchFile(join(dotNextServerDir, "webpack-runtime.js"), chunks);
|
|
81
81
|
patchFile(join(dotNextServerDir, "webpack-api-runtime.js"), chunks);
|
|
82
82
|
}
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { type BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
2
|
import type { ContentUpdater, Plugin } from "@opennextjs/aws/plugins/content-updater.js";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Replaces the dynamic loading of the instrumentation hook, which workerd does not support.
|
|
5
|
+
*
|
|
6
|
+
* Next.js loads `.next/server/instrumentation.js` with a `require()` call built from a path
|
|
7
|
+
* computed at runtime. The loaders are rewritten to either statically `require()` the file that
|
|
8
|
+
* the Next.js build emitted, or to resolve to `null` when the app has no instrumentation hook.
|
|
9
|
+
*
|
|
10
|
+
* @param updater The content updater applying the patches.
|
|
11
|
+
* @param buildOpts The open-next build options.
|
|
12
|
+
* @param options.loadInstrumentation When `false`, the loaders always resolve to `null` so that the
|
|
13
|
+
* instrumentation hook is never registered by this bundle. Defaults to `true`.
|
|
14
|
+
* @returns An esbuild plugin.
|
|
15
|
+
*/
|
|
16
|
+
export declare function patchInstrumentation(updater: ContentUpdater, buildOpts: BuildOptions, { loadInstrumentation }?: {
|
|
17
|
+
loadInstrumentation?: boolean;
|
|
18
|
+
}): Plugin;
|
|
4
19
|
export declare function getNext154Rule(builtInstrumentationPath: string | null): string;
|
|
5
20
|
export declare function getNext15Rule(builtInstrumentationPath: string | null): string;
|
|
6
21
|
export declare function getNext14Rule(builtInstrumentationPath: string | null): string;
|
|
@@ -4,8 +4,21 @@ import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
|
4
4
|
import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
|
|
5
5
|
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
|
|
6
6
|
import { normalizePath } from "../../../utils/normalize-path.js";
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Replaces the dynamic loading of the instrumentation hook, which workerd does not support.
|
|
9
|
+
*
|
|
10
|
+
* Next.js loads `.next/server/instrumentation.js` with a `require()` call built from a path
|
|
11
|
+
* computed at runtime. The loaders are rewritten to either statically `require()` the file that
|
|
12
|
+
* the Next.js build emitted, or to resolve to `null` when the app has no instrumentation hook.
|
|
13
|
+
*
|
|
14
|
+
* @param updater The content updater applying the patches.
|
|
15
|
+
* @param buildOpts The open-next build options.
|
|
16
|
+
* @param options.loadInstrumentation When `false`, the loaders always resolve to `null` so that the
|
|
17
|
+
* instrumentation hook is never registered by this bundle. Defaults to `true`.
|
|
18
|
+
* @returns An esbuild plugin.
|
|
19
|
+
*/
|
|
20
|
+
export function patchInstrumentation(updater, buildOpts, { loadInstrumentation = true } = {}) {
|
|
21
|
+
const builtInstrumentationPath = loadInstrumentation ? getBuiltInstrumentationPath(buildOpts) : null;
|
|
9
22
|
updater.updateContent("patch-instrumentation-next15-4", [
|
|
10
23
|
{
|
|
11
24
|
filter: getCrossPlatformPathRegex(String.raw `/server/lib/router-utils/instrumentation-globals.external\.js$`, {
|
|
@@ -15,6 +15,63 @@ export declare const replaceLoadWebAssemblyModuleRule = "\nrule:\n kind: functi
|
|
|
15
15
|
* the synchronous `WebAssembly.instantiate` to produce the instance's exports.
|
|
16
16
|
*/
|
|
17
17
|
export declare const replaceLoadWebAssemblyRule = "\nrule:\n kind: function_declaration\n has:\n field: name\n regex: \"^loadWebAssembly$\"\nfix: |-\n async function loadWebAssembly(chunkPath, _edgeModule, imports) {\n const mod = await loadWasmChunk(chunkPath);\n const { exports } = await WebAssembly.instantiate(mod, imports);\n return exports;\n }\n";
|
|
18
|
+
/**
|
|
19
|
+
* Replace the `compileModule` helper that Next.js 16.3 emits in the chunks.
|
|
20
|
+
*
|
|
21
|
+
* Next.js 16.3 moved the wasm loading out of `[turbopack]_runtime.js`: it is now emitted on
|
|
22
|
+
* demand in the chunks as `[turbopack-wasm]/node/loadWasm.ts`, which reads the `.wasm` file from
|
|
23
|
+
* the filesystem and compiles it with `WebAssembly.compileStreaming`. Neither is supported by
|
|
24
|
+
* workerd so the helper is rewritten to use the generated `loadWasmChunk`.
|
|
25
|
+
*
|
|
26
|
+
* The emitted code is minified, so the rule matches on the shape of the helper rather than on its
|
|
27
|
+
* name: an async function taking the chunk path as its only parameter and returning the result of
|
|
28
|
+
* `WebAssembly.compileStreaming(...)`.
|
|
29
|
+
*
|
|
30
|
+
* See https://github.com/opennextjs/opennextjs-cloudflare/issues/1342
|
|
31
|
+
*/
|
|
32
|
+
export declare const replaceCompileModuleRule = "\nrule:\n all:\n - pattern:\n context: async function $NAME($PATH) { $$$BODY }\n selector: function_declaration\n - has:\n field: body\n has:\n kind: return_statement\n has:\n pattern: WebAssembly.compileStreaming($$$)\n stopBy: end\nfix: |-\n async function $NAME($PATH) {\n return loadWasmChunk($PATH);\n }\n";
|
|
33
|
+
/**
|
|
34
|
+
* Replace the `instantiate` helper that Next.js 16.3 emits in the chunks.
|
|
35
|
+
*
|
|
36
|
+
* The counterpart of {@link replaceCompileModuleRule} for the helper instantiating the module:
|
|
37
|
+
* `WebAssembly.instantiateStreaming` is not supported by workerd either, so the chunk is loaded
|
|
38
|
+
* with the generated `loadWasmChunk` and instantiated with the synchronous `WebAssembly.instantiate`.
|
|
39
|
+
*
|
|
40
|
+
* The rule matches an async function taking the chunk path and the imports as parameters, and
|
|
41
|
+
* declaring a variable from the result of `WebAssembly.instantiateStreaming(...)`.
|
|
42
|
+
*/
|
|
43
|
+
export declare const replaceInstantiateModuleRule = "\nrule:\n all:\n - pattern:\n context: async function $NAME($PATH, $IMPORTS) { $$$BODY }\n selector: function_declaration\n - has:\n field: body\n has:\n kind: lexical_declaration\n has:\n pattern: WebAssembly.instantiateStreaming($$$)\n stopBy: end\nfix: |-\n async function $NAME($PATH, $IMPORTS) {\n const module = await loadWasmChunk($PATH);\n const { exports } = await WebAssembly.instantiate(module, $IMPORTS);\n return exports;\n }\n";
|
|
44
|
+
/**
|
|
45
|
+
* Inline the dynamic chunk requires of the Turbopack runtime.
|
|
46
|
+
*
|
|
47
|
+
* The runtime resolves the chunks it needs at runtime, which workerd does not support.
|
|
48
|
+
* The chunks are inlined so that they are statically bundled.
|
|
49
|
+
*
|
|
50
|
+
* @param code The code of the Turbopack runtime.
|
|
51
|
+
* @param filePath Path to the Turbopack runtime, in the OpenNext output.
|
|
52
|
+
* @param tracedFiles The files traced by Next.js, copied next to the runtime.
|
|
53
|
+
* @returns The patched code.
|
|
54
|
+
*/
|
|
55
|
+
export declare function patchTurbopackRuntimeCode({ code, filePath, tracedFiles, }: {
|
|
56
|
+
code: string;
|
|
57
|
+
filePath: string;
|
|
58
|
+
tracedFiles: string[];
|
|
59
|
+
}): string;
|
|
60
|
+
/**
|
|
61
|
+
* Replace the wasm helpers that Next.js 16.3 emits in the Turbopack chunks.
|
|
62
|
+
*
|
|
63
|
+
* Until Next.js 16.2 the wasm loaders lived in `[turbopack]_runtime.js` and were patched by
|
|
64
|
+
* {@link patchTurbopackRuntimeCode}. Next.js 16.3 emits them on demand in the chunks instead, so
|
|
65
|
+
* the chunks need to be patched too.
|
|
66
|
+
*
|
|
67
|
+
* @param code The code of the Turbopack chunk.
|
|
68
|
+
* @param tracedFiles The files traced by Next.js.
|
|
69
|
+
* @returns The patched code, or `code` unchanged when the chunk has no wasm helper.
|
|
70
|
+
*/
|
|
71
|
+
export declare function patchTurbopackWasmChunkCode({ code, tracedFiles, }: {
|
|
72
|
+
code: string;
|
|
73
|
+
tracedFiles: string[];
|
|
74
|
+
}): string;
|
|
18
75
|
export declare const patchTurbopackRuntime: CodePatcher;
|
|
19
76
|
/**
|
|
20
77
|
* Generate a `loadWasmChunk` function that maps a `.next`-relative chunk path to a
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
|
|
3
|
+
import { applyRule, parseCode, patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
|
|
4
4
|
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
|
|
5
|
+
import { normalizePath } from "../../../utils/normalize-path.js";
|
|
5
6
|
const inlineChunksRule = `
|
|
6
7
|
rule:
|
|
7
8
|
kind: call_expression
|
|
@@ -47,6 +48,68 @@ fix: |-
|
|
|
47
48
|
return exports;
|
|
48
49
|
}
|
|
49
50
|
`;
|
|
51
|
+
/**
|
|
52
|
+
* Replace the `compileModule` helper that Next.js 16.3 emits in the chunks.
|
|
53
|
+
*
|
|
54
|
+
* Next.js 16.3 moved the wasm loading out of `[turbopack]_runtime.js`: it is now emitted on
|
|
55
|
+
* demand in the chunks as `[turbopack-wasm]/node/loadWasm.ts`, which reads the `.wasm` file from
|
|
56
|
+
* the filesystem and compiles it with `WebAssembly.compileStreaming`. Neither is supported by
|
|
57
|
+
* workerd so the helper is rewritten to use the generated `loadWasmChunk`.
|
|
58
|
+
*
|
|
59
|
+
* The emitted code is minified, so the rule matches on the shape of the helper rather than on its
|
|
60
|
+
* name: an async function taking the chunk path as its only parameter and returning the result of
|
|
61
|
+
* `WebAssembly.compileStreaming(...)`.
|
|
62
|
+
*
|
|
63
|
+
* See https://github.com/opennextjs/opennextjs-cloudflare/issues/1342
|
|
64
|
+
*/
|
|
65
|
+
export const replaceCompileModuleRule = `
|
|
66
|
+
rule:
|
|
67
|
+
all:
|
|
68
|
+
- pattern:
|
|
69
|
+
context: async function $NAME($PATH) { $$$BODY }
|
|
70
|
+
selector: function_declaration
|
|
71
|
+
- has:
|
|
72
|
+
field: body
|
|
73
|
+
has:
|
|
74
|
+
kind: return_statement
|
|
75
|
+
has:
|
|
76
|
+
pattern: WebAssembly.compileStreaming($$$)
|
|
77
|
+
stopBy: end
|
|
78
|
+
fix: |-
|
|
79
|
+
async function $NAME($PATH) {
|
|
80
|
+
return loadWasmChunk($PATH);
|
|
81
|
+
}
|
|
82
|
+
`;
|
|
83
|
+
/**
|
|
84
|
+
* Replace the `instantiate` helper that Next.js 16.3 emits in the chunks.
|
|
85
|
+
*
|
|
86
|
+
* The counterpart of {@link replaceCompileModuleRule} for the helper instantiating the module:
|
|
87
|
+
* `WebAssembly.instantiateStreaming` is not supported by workerd either, so the chunk is loaded
|
|
88
|
+
* with the generated `loadWasmChunk` and instantiated with the synchronous `WebAssembly.instantiate`.
|
|
89
|
+
*
|
|
90
|
+
* The rule matches an async function taking the chunk path and the imports as parameters, and
|
|
91
|
+
* declaring a variable from the result of `WebAssembly.instantiateStreaming(...)`.
|
|
92
|
+
*/
|
|
93
|
+
export const replaceInstantiateModuleRule = `
|
|
94
|
+
rule:
|
|
95
|
+
all:
|
|
96
|
+
- pattern:
|
|
97
|
+
context: async function $NAME($PATH, $IMPORTS) { $$$BODY }
|
|
98
|
+
selector: function_declaration
|
|
99
|
+
- has:
|
|
100
|
+
field: body
|
|
101
|
+
has:
|
|
102
|
+
kind: lexical_declaration
|
|
103
|
+
has:
|
|
104
|
+
pattern: WebAssembly.instantiateStreaming($$$)
|
|
105
|
+
stopBy: end
|
|
106
|
+
fix: |-
|
|
107
|
+
async function $NAME($PATH, $IMPORTS) {
|
|
108
|
+
const module = await loadWasmChunk($PATH);
|
|
109
|
+
const { exports } = await WebAssembly.instantiate(module, $IMPORTS);
|
|
110
|
+
return exports;
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
50
113
|
/**
|
|
51
114
|
* Discover Turbopack external module mappings by reading symlinks in .next/node_modules/.
|
|
52
115
|
*
|
|
@@ -220,6 +283,52 @@ function discoverExternalSubpaths(mappings, tracedFiles) {
|
|
|
220
283
|
}
|
|
221
284
|
return subpaths;
|
|
222
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* Inline the dynamic chunk requires of the Turbopack runtime.
|
|
288
|
+
*
|
|
289
|
+
* The runtime resolves the chunks it needs at runtime, which workerd does not support.
|
|
290
|
+
* The chunks are inlined so that they are statically bundled.
|
|
291
|
+
*
|
|
292
|
+
* @param code The code of the Turbopack runtime.
|
|
293
|
+
* @param filePath Path to the Turbopack runtime, in the OpenNext output.
|
|
294
|
+
* @param tracedFiles The files traced by Next.js, copied next to the runtime.
|
|
295
|
+
* @returns The patched code.
|
|
296
|
+
*/
|
|
297
|
+
export function patchTurbopackRuntimeCode({ code, filePath, tracedFiles, }) {
|
|
298
|
+
tracedFiles = tracedFiles.map(normalizePath);
|
|
299
|
+
filePath = normalizePath(filePath);
|
|
300
|
+
const mappings = discoverExternalModuleMappings(filePath);
|
|
301
|
+
const externalImportRule = buildExternalImportRule(mappings, tracedFiles, code);
|
|
302
|
+
let patched = patchCode(code, externalImportRule);
|
|
303
|
+
patched = patchCode(patched, inlineChunksRule);
|
|
304
|
+
patched = patchCode(patched, replaceLoadWebAssemblyModuleRule);
|
|
305
|
+
patched = patchCode(patched, replaceLoadWebAssemblyRule);
|
|
306
|
+
return `${patched}
|
|
307
|
+
${inlineChunksFn(tracedFiles)}\n${loadWasmChunkFn(tracedFiles)}`;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Replace the wasm helpers that Next.js 16.3 emits in the Turbopack chunks.
|
|
311
|
+
*
|
|
312
|
+
* Until Next.js 16.2 the wasm loaders lived in `[turbopack]_runtime.js` and were patched by
|
|
313
|
+
* {@link patchTurbopackRuntimeCode}. Next.js 16.3 emits them on demand in the chunks instead, so
|
|
314
|
+
* the chunks need to be patched too.
|
|
315
|
+
*
|
|
316
|
+
* @param code The code of the Turbopack chunk.
|
|
317
|
+
* @param tracedFiles The files traced by Next.js.
|
|
318
|
+
* @returns The patched code, or `code` unchanged when the chunk has no wasm helper.
|
|
319
|
+
*/
|
|
320
|
+
export function patchTurbopackWasmChunkCode({ code, tracedFiles, }) {
|
|
321
|
+
const root = parseCode(code);
|
|
322
|
+
// The 2 rules can not match the same function: they differ by the arity of the helper.
|
|
323
|
+
const edits = [
|
|
324
|
+
...applyRule(replaceCompileModuleRule, root).edits,
|
|
325
|
+
...applyRule(replaceInstantiateModuleRule, root).edits,
|
|
326
|
+
];
|
|
327
|
+
if (edits.length === 0) {
|
|
328
|
+
return code;
|
|
329
|
+
}
|
|
330
|
+
return `${root.commitEdits(edits)}\n${loadWasmChunkFn(tracedFiles.map(normalizePath))}`;
|
|
331
|
+
}
|
|
223
332
|
export const patchTurbopackRuntime = {
|
|
224
333
|
name: "inline-turbopack-chunks",
|
|
225
334
|
patches: [
|
|
@@ -229,16 +338,18 @@ export const patchTurbopackRuntime = {
|
|
|
229
338
|
escape: false,
|
|
230
339
|
}),
|
|
231
340
|
contentFilter: /loadRuntimeChunkPath/,
|
|
232
|
-
patchCode: async ({ code, tracedFiles, filePath }) => {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
},
|
|
341
|
+
patchCode: async ({ code, tracedFiles, filePath }) => patchTurbopackRuntimeCode({ code, filePath, tracedFiles }),
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
// Next.js 16.3.0 moved the wasm loaders out of the Turbopack runtime and started
|
|
345
|
+
// emitting them on demand in the chunks that need them. Earlier versions are handled
|
|
346
|
+
// by the runtime patch above.
|
|
347
|
+
versions: ">=16.3.0",
|
|
348
|
+
pathFilter: getCrossPlatformPathRegex(String.raw `/\.next/server/chunks/.+\.js$`, {
|
|
349
|
+
escape: false,
|
|
350
|
+
}),
|
|
351
|
+
contentFilter: /WebAssembly\.(compileStreaming|instantiateStreaming)/,
|
|
352
|
+
patchCode: async ({ code, tracedFiles }) => patchTurbopackWasmChunkCode({ code, tracedFiles }),
|
|
242
353
|
},
|
|
243
354
|
],
|
|
244
355
|
};
|
|
@@ -34,7 +34,7 @@ export function findWranglerConfig(appDir) {
|
|
|
34
34
|
* @returns An object containing a `cachingEnabled` which indicates whether caching has been set up during the wrangler
|
|
35
35
|
* config file creation or not
|
|
36
36
|
*/
|
|
37
|
-
export async function createWranglerConfigFile(projectDir, defaultCompatDate = "2026-
|
|
37
|
+
export async function createWranglerConfigFile(projectDir, defaultCompatDate = "2026-08-01") {
|
|
38
38
|
const workerName = getWorkerName(projectDir);
|
|
39
39
|
const compatibilityDate = (await getLatestCompatDate()) ?? defaultCompatDate;
|
|
40
40
|
const wranglerConfigStr = readFileSync(join(getPackageTemplatesDirPath(), "wrangler.jsonc"), "utf8")
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opennextjs/cloudflare",
|
|
3
3
|
"description": "Cloudflare builder for next apps",
|
|
4
|
-
"version": "1.20.
|
|
4
|
+
"version": "1.20.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"opennextjs-cloudflare": "dist/cli/index.js"
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@ast-grep/napi": "^0.40.5",
|
|
46
46
|
"@dotenvx/dotenvx": "1.31.0",
|
|
47
|
-
"@opennextjs/aws": "4.
|
|
47
|
+
"@opennextjs/aws": "4.1.1",
|
|
48
48
|
"ci-info": "^4.2.0",
|
|
49
49
|
"cloudflare": "^4.4.1",
|
|
50
50
|
"comment-json": "^4.5.1",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"eslint-plugin-unicorn": "^55.0.0",
|
|
71
71
|
"globals": "^15.9.0",
|
|
72
72
|
"mock-fs": "^5.4.1",
|
|
73
|
-
"next": "^15.5.
|
|
73
|
+
"next": "^15.5.24",
|
|
74
74
|
"picomatch": "^4.0.2",
|
|
75
75
|
"rclone.js": "^0.6.6",
|
|
76
76
|
"rimraf": "^6.0.1",
|
|
@@ -79,9 +79,9 @@
|
|
|
79
79
|
"vitest": "^4.1.4"
|
|
80
80
|
},
|
|
81
81
|
"peerDependencies": {
|
|
82
|
-
"next": ">=15.5.
|
|
82
|
+
"next": ">=15.5.24 <16 || >=16.3.3",
|
|
83
83
|
"rclone.js": "^0.6.6",
|
|
84
|
-
"wrangler": "^4.
|
|
84
|
+
"wrangler": "^4.125.0"
|
|
85
85
|
},
|
|
86
86
|
"peerDependenciesMeta": {
|
|
87
87
|
"rclone.js": {
|