@opennextjs/cloudflare 1.14.10 → 1.15.0
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 +0 -3
- package/dist/cli/build/bundle-server.js +10 -3
- package/dist/cli/build/open-next/createServerBundle.js +1 -1
- package/dist/cli/build/patches/ast/patch-vercel-og-library.d.ts +2 -1
- package/dist/cli/build/patches/ast/patch-vercel-og-library.js +18 -11
- package/dist/cli/build/patches/ast/vercel-og.d.ts +3 -0
- package/dist/cli/build/patches/ast/vercel-og.js +3 -0
- package/dist/cli/build/patches/plugins/require-hook.js +2 -2
- package/dist/cli/build/patches/plugins/shim-react.d.ts +15 -0
- package/dist/cli/build/patches/plugins/shim-react.js +27 -0
- package/dist/cli/commands/utils.d.ts +1 -1
- package/package.json +2 -2
package/dist/cli/build/build.js
CHANGED
|
@@ -79,9 +79,6 @@ async function ensureNextjsVersionSupported({ nextVersion }) {
|
|
|
79
79
|
logger.error("Next.js version unsupported, please upgrade to version 14.2 or greater.");
|
|
80
80
|
process.exit(1);
|
|
81
81
|
}
|
|
82
|
-
if (buildHelper.compareSemver(nextVersion, ">=", "16")) {
|
|
83
|
-
logger.warn("Next.js 16 is not fully supported yet! Some features may not work as expected.");
|
|
84
|
-
}
|
|
85
82
|
const { default: { version: wranglerVersion }, } = await import("wrangler/package.json", { with: { type: "json" } });
|
|
86
83
|
// We need a version of workerd that has a fix for setImmediate for Next.js 16.1+
|
|
87
84
|
// See:
|
|
@@ -3,6 +3,7 @@ import { readFile, writeFile } from "node:fs/promises";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
|
|
6
|
+
import * as buildHelper from "@opennextjs/aws/build/helper.js";
|
|
6
7
|
import { ContentUpdater } from "@opennextjs/aws/plugins/content-updater.js";
|
|
7
8
|
import { build } from "esbuild";
|
|
8
9
|
import { getOpenNextConfig } from "../../api/config.js";
|
|
@@ -20,6 +21,7 @@ import { patchDepdDeprecations } from "./patches/plugins/patch-depd-deprecations
|
|
|
20
21
|
import { fixRequire } from "./patches/plugins/require.js";
|
|
21
22
|
import { shimRequireHook } from "./patches/plugins/require-hook.js";
|
|
22
23
|
import { patchRouteModules } from "./patches/plugins/route-module.js";
|
|
24
|
+
import { shimReact } from "./patches/plugins/shim-react.js";
|
|
23
25
|
import { setWranglerExternal } from "./patches/plugins/wrangler-external.js";
|
|
24
26
|
import { copyPackageCliFiles, needsExperimentalReact, normalizePath } from "./utils/index.js";
|
|
25
27
|
/** The dist directory of the Cloudflare adapter package */
|
|
@@ -46,10 +48,10 @@ export async function bundleServer(buildOpts, projectOpts) {
|
|
|
46
48
|
const dotNextPath = path.join(outputDir, "server-functions/default", getPackagePath(buildOpts), ".next");
|
|
47
49
|
const serverFiles = path.join(dotNextPath, "required-server-files.json");
|
|
48
50
|
const nextConfig = JSON.parse(fs.readFileSync(serverFiles, "utf-8")).config;
|
|
49
|
-
const useTurbopack =
|
|
51
|
+
const useTurbopack = buildHelper.getBundlerRuntime(buildOpts) === "turbopack";
|
|
50
52
|
console.log(`\x1b[35m⚙️ Bundling the OpenNext server...\n\x1b[0m`);
|
|
51
53
|
await patchWebpackRuntime(buildOpts);
|
|
52
|
-
patchVercelOgLibrary(buildOpts);
|
|
54
|
+
const useOg = patchVercelOgLibrary(buildOpts);
|
|
53
55
|
const outputPath = path.join(outputDir, "server-functions", "default");
|
|
54
56
|
const packagePath = getPackagePath(buildOpts);
|
|
55
57
|
const openNextServer = path.join(outputPath, packagePath, `index.mjs`);
|
|
@@ -79,6 +81,7 @@ export async function bundleServer(buildOpts, projectOpts) {
|
|
|
79
81
|
conditions: getOpenNextConfig(buildOpts).cloudflare?.useWorkerdCondition === false ? [] : ["workerd"],
|
|
80
82
|
plugins: [
|
|
81
83
|
shimRequireHook(buildOpts),
|
|
84
|
+
shimReact(buildOpts),
|
|
82
85
|
inlineDynamicRequires(updater, buildOpts),
|
|
83
86
|
setWranglerExternal(),
|
|
84
87
|
fixRequire(updater),
|
|
@@ -95,7 +98,11 @@ export async function bundleServer(buildOpts, projectOpts) {
|
|
|
95
98
|
// Apply updater updates, must be the last plugin
|
|
96
99
|
updater.plugin,
|
|
97
100
|
],
|
|
98
|
-
external: [
|
|
101
|
+
external: [
|
|
102
|
+
"./middleware/handler.mjs",
|
|
103
|
+
// Do not bundle og when it is not used
|
|
104
|
+
...(useOg ? [] : ["next/dist/compiled/@vercel/og/index.edge.js"]),
|
|
105
|
+
],
|
|
99
106
|
alias: {
|
|
100
107
|
// Workers have `fetch` so the `node-fetch` polyfill is not needed
|
|
101
108
|
"next/dist/compiled/node-fetch": path.join(buildOpts.outputDir, "cloudflare-templates/shims/fetch.js"),
|
|
@@ -137,7 +137,7 @@ async function generateBundle(name, options, fnOptions, codeCustomization) {
|
|
|
137
137
|
awsPatches.patchUnstableCacheForISR,
|
|
138
138
|
awsPatches.patchUseCacheForISR,
|
|
139
139
|
awsPatches.patchNextServer,
|
|
140
|
-
awsPatches.
|
|
140
|
+
awsPatches.getEnvVarsPatch(options),
|
|
141
141
|
awsPatches.patchBackgroundRevalidation,
|
|
142
142
|
awsPatches.patchNodeEnvironment,
|
|
143
143
|
// Cloudflare specific patches
|
|
@@ -3,5 +3,6 @@ import type { BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
|
3
3
|
* Patches the usage of @vercel/og to be compatible with Cloudflare Workers.
|
|
4
4
|
*
|
|
5
5
|
* @param buildOpts Build options.
|
|
6
|
+
* @returns Whether the @vercel/og library is used.
|
|
6
7
|
*/
|
|
7
|
-
export declare function patchVercelOgLibrary(buildOpts: BuildOptions):
|
|
8
|
+
export declare function patchVercelOgLibrary(buildOpts: BuildOptions): boolean;
|
|
@@ -8,19 +8,24 @@ import { patchVercelOgFallbackFont, patchVercelOgImport } from "./vercel-og.js";
|
|
|
8
8
|
* Patches the usage of @vercel/og to be compatible with Cloudflare Workers.
|
|
9
9
|
*
|
|
10
10
|
* @param buildOpts Build options.
|
|
11
|
+
* @returns Whether the @vercel/og library is used.
|
|
11
12
|
*/
|
|
12
13
|
export function patchVercelOgLibrary(buildOpts) {
|
|
13
14
|
const { appBuildOutputPath, outputDir } = buildOpts;
|
|
14
15
|
const functionsPath = path.join(outputDir, "server-functions/default");
|
|
15
16
|
const packagePath = path.join(functionsPath, getPackagePath(buildOpts));
|
|
17
|
+
let useOg = false;
|
|
16
18
|
for (const traceInfoPath of globSync(path.join(appBuildOutputPath, ".next/server/**/*.nft.json"), {
|
|
17
19
|
windowsPathsNoEscape: true,
|
|
18
20
|
})) {
|
|
19
|
-
|
|
21
|
+
// Look for the Node version of the traced @vercel/og files
|
|
20
22
|
const traceInfo = JSON.parse(readFileSync(traceInfoPath, { encoding: "utf8" }));
|
|
21
23
|
const tracedNodePath = traceInfo.files.find((p) => p.endsWith("@vercel/og/index.node.js"));
|
|
22
24
|
if (!tracedNodePath)
|
|
23
25
|
continue;
|
|
26
|
+
// If we are here, it means the application is using the @vercel/og library
|
|
27
|
+
// and there is an `index.edge.js` colocated file that we need to copy and patch.
|
|
28
|
+
useOg = true;
|
|
24
29
|
const outputDir = getOutputDir({ functionsPath, packagePath });
|
|
25
30
|
const outputEdgePath = path.join(outputDir, "index.edge.js");
|
|
26
31
|
// Ensure the edge version is available in the OpenNext node_modules.
|
|
@@ -28,12 +33,11 @@ export function patchVercelOgLibrary(buildOpts) {
|
|
|
28
33
|
const tracedEdgePath = path.join(path.dirname(traceInfoPath), tracedNodePath.replace("index.node.js", "index.edge.js"));
|
|
29
34
|
copyFileSync(tracedEdgePath, outputEdgePath);
|
|
30
35
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
writeFileSync(outputEdgePath, node.commitEdits(edits));
|
|
36
|
+
// Change font fetches in the library to use imports.
|
|
37
|
+
{
|
|
38
|
+
const ast = parseFile(outputEdgePath);
|
|
39
|
+
const { edits, matches } = patchVercelOgFallbackFont(ast);
|
|
40
|
+
writeFileSync(outputEdgePath, ast.commitEdits(edits));
|
|
37
41
|
if (matches.length > 0) {
|
|
38
42
|
const fontFileName = matches[0].getMatch("PATH").text();
|
|
39
43
|
renameSync(path.join(outputDir, fontFileName), path.join(outputDir, `${fontFileName}.bin`));
|
|
@@ -41,11 +45,14 @@ export function patchVercelOgLibrary(buildOpts) {
|
|
|
41
45
|
}
|
|
42
46
|
// Change node imports for the library to edge imports.
|
|
43
47
|
// This is only useful when turbopack is not used to bundle the function.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
{
|
|
49
|
+
const routeFilePath = traceInfoPath.replace(appBuildOutputPath, packagePath).replace(".nft.json", "");
|
|
50
|
+
const ast = parseFile(routeFilePath);
|
|
51
|
+
const { edits } = patchVercelOgImport(ast);
|
|
52
|
+
writeFileSync(routeFilePath, ast.commitEdits(edits));
|
|
53
|
+
}
|
|
48
54
|
}
|
|
55
|
+
return useOg;
|
|
49
56
|
}
|
|
50
57
|
function getOutputDir(opts) {
|
|
51
58
|
const vercelOgNodeModulePath = "node_modules/next/dist/compiled/@vercel/og";
|
|
@@ -14,6 +14,9 @@ export declare const vercelOgFallbackFontRule = "\nrule:\n kind: variable_decla
|
|
|
14
14
|
/**
|
|
15
15
|
* Patches the default font fetching to use a .bin import.
|
|
16
16
|
*
|
|
17
|
+
* We use `.bin` extension as they are added as modules in the wrangler bundler.
|
|
18
|
+
* We would need to add a rule to handle `.ttf` otherwise.
|
|
19
|
+
*
|
|
17
20
|
* @param root Root node.
|
|
18
21
|
* @returns Results of applying the rule.
|
|
19
22
|
*/
|
|
@@ -50,6 +50,9 @@ fix: |-
|
|
|
50
50
|
/**
|
|
51
51
|
* Patches the default font fetching to use a .bin import.
|
|
52
52
|
*
|
|
53
|
+
* We use `.bin` extension as they are added as modules in the wrangler bundler.
|
|
54
|
+
* We would need to add a rule to handle `.ttf` otherwise.
|
|
55
|
+
*
|
|
53
56
|
* @param root Root node.
|
|
54
57
|
* @returns Results of applying the rule.
|
|
55
58
|
*/
|
|
@@ -3,9 +3,9 @@ import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
|
|
|
3
3
|
export function shimRequireHook(options) {
|
|
4
4
|
const emptyShimPath = join(options.outputDir, "cloudflare-templates/shims/empty.js");
|
|
5
5
|
return {
|
|
6
|
-
name: "
|
|
6
|
+
name: "require-hook-shim",
|
|
7
7
|
setup(build) {
|
|
8
|
-
//
|
|
8
|
+
// We (empty) shim require-hook modules as they generate problematic code that uses requires
|
|
9
9
|
build.onResolve({ filter: getCrossPlatformPathRegex(String.raw `^\./require-hook$`, { escape: false }) }, () => ({
|
|
10
10
|
path: emptyShimPath,
|
|
11
11
|
}));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BuildOptions } from "@opennextjs/aws/build/helper.js";
|
|
2
|
+
import type { Plugin } from "esbuild";
|
|
3
|
+
/**
|
|
4
|
+
* `react-dom/server.edge` requires:
|
|
5
|
+
* - `react-dom-server.edge.production.js`
|
|
6
|
+
* - `react-dom-server.browser.production.js`
|
|
7
|
+
* - `react-dom-server-legacy.browser.production.js`
|
|
8
|
+
*
|
|
9
|
+
* However only the first one is needed in the Cloudflare Workers environment.
|
|
10
|
+
* The other two can be shimmed to an empty module to reduce the bundle size.
|
|
11
|
+
*
|
|
12
|
+
* @param options Build options
|
|
13
|
+
* @returns An ESBuild plugin that shims unnecessary React modules
|
|
14
|
+
*/
|
|
15
|
+
export declare function shimReact(options: BuildOptions): Plugin;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
|
|
3
|
+
/**
|
|
4
|
+
* `react-dom/server.edge` requires:
|
|
5
|
+
* - `react-dom-server.edge.production.js`
|
|
6
|
+
* - `react-dom-server.browser.production.js`
|
|
7
|
+
* - `react-dom-server-legacy.browser.production.js`
|
|
8
|
+
*
|
|
9
|
+
* However only the first one is needed in the Cloudflare Workers environment.
|
|
10
|
+
* The other two can be shimmed to an empty module to reduce the bundle size.
|
|
11
|
+
*
|
|
12
|
+
* @param options Build options
|
|
13
|
+
* @returns An ESBuild plugin that shims unnecessary React modules
|
|
14
|
+
*/
|
|
15
|
+
export function shimReact(options) {
|
|
16
|
+
const emptyShimPath = join(options.outputDir, "cloudflare-templates/shims/empty.js");
|
|
17
|
+
return {
|
|
18
|
+
name: "react-shim",
|
|
19
|
+
setup(build) {
|
|
20
|
+
build.onResolve({
|
|
21
|
+
filter: getCrossPlatformPathRegex(String.raw `(react-dom-server\.browser\.production\.js|react-dom-server-legacy\.browser\.production\.js)$`, { escape: false }),
|
|
22
|
+
}, () => ({
|
|
23
|
+
path: emptyShimPath,
|
|
24
|
+
}));
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -56,7 +56,7 @@ export declare function getNormalizedOptions(config: OpenNextConfig, buildDir?:
|
|
|
56
56
|
openNextVersion: string;
|
|
57
57
|
openNextDistDir: string;
|
|
58
58
|
outputDir: string;
|
|
59
|
-
packager: "
|
|
59
|
+
packager: "npm" | "pnpm" | "yarn" | "bun";
|
|
60
60
|
tempBuildDir: string;
|
|
61
61
|
};
|
|
62
62
|
/**
|
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.
|
|
4
|
+
"version": "1.15.0",
|
|
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.0",
|
|
46
46
|
"@dotenvx/dotenvx": "1.31.0",
|
|
47
|
-
"@opennextjs/aws": "3.9.
|
|
47
|
+
"@opennextjs/aws": "3.9.11",
|
|
48
48
|
"cloudflare": "^4.4.1",
|
|
49
49
|
"enquirer": "^2.4.1",
|
|
50
50
|
"glob": "^12.0.0",
|