Skip to content

Commit 112ca67

Browse files
authored
Merge branch 'opennextjs:main' into type
2 parents 08fa5d0 + a2679bf commit 112ca67

15 files changed

Lines changed: 646 additions & 55 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@opennextjs/cloudflare": patch
3+
---
4+
5+
Stop bundling `@vercel/og` (and its ~1.4 MiB `resvg.wasm`) when the app does not use it.
6+
7+
Next.js's `externalImport` helper keeps a dynamic `import("next/dist/compiled/@vercel/og/index.edge.js")` in the emitted handler even for apps that never use `ImageResponse` / `opengraph-image`. Previously this module was marked as `external` when `useOg` was `false`, which left Wrangler to resolve and bundle it — pulling in ~800 KiB of JS plus `resvg.wasm` and pushing many Workers over the Cloudflare free-tier 3 MiB gzip limit.
8+
9+
When `useOg` is `false`, the edge entry is now aliased to the existing `throw.js` shim, so the unreachable dynamic import resolves to a tiny module and the real `@vercel/og` library is no longer pulled into the Worker bundle.

packages/cloudflare/CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
# @opennextjs/cloudflare
22

3+
## 1.19.3
4+
5+
### Patch Changes
6+
7+
- [#1215](https://github.com/opennextjs/opennextjs-cloudflare/pull/1215) [`608893e`](https://github.com/opennextjs/opennextjs-cloudflare/commit/608893e63e1ee16d07c7ec42da979657cf2a62bd) Thanks [@vicb](https://github.com/vicb)! - Factor large repeated values in manifests
8+
9+
This reduce the size of the generated code.
10+
11+
- [#1218](https://github.com/opennextjs/opennextjs-cloudflare/pull/1218) [`f0d0226`](https://github.com/opennextjs/opennextjs-cloudflare/commit/f0d022685b24881a142bb01005ff78089be8c8d3) Thanks [@314systems](https://github.com/314systems)! - remove `process.version` override
12+
13+
Remove process.version / process.versions.node overrides now that [unjs/unenv#493](https://github.com/unjs/unenv/pull/493) is merged and shipped in [[email protected]](https://github.com/unjs/unenv/releases/tag/v2.0.0-rc.16) (project uses 2.0.0-rc.24)
14+
15+
- [#1199](https://github.com/opennextjs/opennextjs-cloudflare/pull/1199) [`32594d6`](https://github.com/opennextjs/opennextjs-cloudflare/commit/32594d6a921c5ebdbe25f38635bb2c9dabdcbff1) Thanks [@SdSadat](https://github.com/SdSadat)! - fix(cli): fail fast in non-TTY environments instead of hanging on config-creation prompts
16+
17+
When `open-next.config.ts` (or `wrangler.(toml|json|jsonc)`) is missing, the CLI
18+
prompts the user to auto-create it. In non-TTY environments (Cloudflare Workers
19+
Builds, Docker, CI) the Enquirer prompt can't read stdin, so the build hangs or
20+
fails with a truncated prompt and a cryptic exit code — the user sees
21+
`? Missing required open-next.config.ts file, do you want to create one? (Y/n)`
22+
and then ` ELIFECYCLE Command failed with exit code 13`, with no hint at what
23+
to do next.
24+
25+
Now, in non-interactive environments, both prompts throw an actionable error
26+
with the exact template to paste (for `open-next.config.ts`) or point at the
27+
existing `--skipWranglerConfigCheck` / `SKIP_WRANGLER_CONFIG_CHECK` escape
28+
hatch (for the wrangler config). Interactive behavior is unchanged.
29+
330
## 1.19.2
431

532
### Patch Changes

packages/cloudflare/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@opennextjs/cloudflare",
33
"description": "Cloudflare builder for next apps",
4-
"version": "1.19.2",
4+
"version": "1.19.3",
55
"type": "module",
66
"scripts": {
77
"clean": "rimraf dist",
@@ -55,6 +55,7 @@
5555
"@ast-grep/napi": "^0.40.5",
5656
"@dotenvx/dotenvx": "catalog:",
5757
"@opennextjs/aws": "3.10.2",
58+
"ci-info": "^4.2.0",
5859
"cloudflare": "^4.4.1",
5960
"comment-json": "^4.5.1",
6061
"enquirer": "^2.4.1",

packages/cloudflare/src/api/overrides/tag-cache/do-sharded-tag-cache.spec.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ describe("DOShardedTagCache", () => {
271271

272272
it("should only read tag data once on a regional-cache miss", async () => {
273273
const putMock = vi.fn();
274-
// @ts-expect-error - Defined on cloudfare context
274+
// @ts-expect-error - Defined on cloudflare context
275275
globalThis.caches = {
276276
open: vi.fn().mockResolvedValue({
277277
match: vi.fn().mockResolvedValue(null),
@@ -294,7 +294,7 @@ describe("DOShardedTagCache", () => {
294294
"http://local.cache/shard/tag-hard;shard-1?tag=tag1",
295295
expect.any(Response)
296296
);
297-
// @ts-expect-error - Defined on cloudfare context
297+
// @ts-expect-error - Defined on cloudflare context
298298
globalThis.caches = undefined;
299299
});
300300

@@ -437,15 +437,15 @@ describe("DOShardedTagCache", () => {
437437
});
438438

439439
it("should try to return the cache instance if regional cache is enabled", async () => {
440-
// @ts-expect-error - Defined on cloudfare context
440+
// @ts-expect-error - Defined on cloudflare context
441441
globalThis.caches = {
442442
open: vi.fn().mockResolvedValue("cache"),
443443
};
444444
const cache = shardedDOTagCache({ baseShardSize: 4, regionalCache: true });
445445
expect(cache.localCache).toBeUndefined();
446446
expect(await cache.getCacheInstance()).toBe("cache");
447447
expect(cache.localCache).toBe("cache");
448-
// @ts-expect-error - Defined on cloudfare context
448+
// @ts-expect-error - Defined on cloudflare context
449449
globalThis.caches = undefined;
450450
});
451451
});
@@ -462,7 +462,7 @@ describe("DOShardedTagCache", () => {
462462
});
463463

464464
it("should call .match on the cache", async () => {
465-
// @ts-expect-error - Defined on cloudfare context
465+
// @ts-expect-error - Defined on cloudflare context
466466
globalThis.caches = {
467467
open: vi.fn().mockResolvedValue({
468468
match: vi.fn().mockResolvedValue(new Response("1234567")),
@@ -478,13 +478,13 @@ describe("DOShardedTagCache", () => {
478478
expect(cacheResult.length).toBe(1);
479479
// "1234567" is a plain number (old format) → backward-compat parse
480480
expect(cacheResult[0]).toEqual({ tag: "tag1", revalidatedAt: 1234567, stale: 1234567, expire: null });
481-
// @ts-expect-error - Defined on cloudfare context
481+
// @ts-expect-error - Defined on cloudflare context
482482
globalThis.caches = undefined;
483483
});
484484

485485
it("should parse new JSON object format from the cache", async () => {
486486
const stored = JSON.stringify({ revalidatedAt: 1000, stale: 500, expire: 9999 });
487-
// @ts-expect-error - Defined on cloudfare context
487+
// @ts-expect-error - Defined on cloudflare context
488488
globalThis.caches = {
489489
open: vi.fn().mockResolvedValue({
490490
match: vi.fn().mockResolvedValue(new Response(stored)),
@@ -494,7 +494,7 @@ describe("DOShardedTagCache", () => {
494494
const doId = new DOId({ baseShardId: "shard-1", numberOfReplicas: 1, shardType: "hard" });
495495
const cacheResult = await cache.getFromRegionalCache({ doId, tags: ["tag1"] });
496496
expect(cacheResult[0]).toEqual({ tag: "tag1", revalidatedAt: 1000, stale: 500, expire: 9999 });
497-
// @ts-expect-error - Defined on cloudfare context
497+
// @ts-expect-error - Defined on cloudflare context
498498
globalThis.caches = undefined;
499499
});
500500
});
@@ -513,7 +513,7 @@ describe("DOShardedTagCache", () => {
513513

514514
it("should put the tags in the regional cache if the tags exists in the DO", async () => {
515515
const putMock = vi.fn();
516-
// @ts-expect-error - Defined on cloudfare context
516+
// @ts-expect-error - Defined on cloudflare context
517517
globalThis.caches = {
518518
open: vi.fn().mockResolvedValue({
519519
put: putMock,
@@ -535,13 +535,13 @@ describe("DOShardedTagCache", () => {
535535
"http://local.cache/shard/tag-hard;shard-1?tag=tag1",
536536
expect.any(Response)
537537
);
538-
// @ts-expect-error - Defined on cloudfare context
538+
// @ts-expect-error - Defined on cloudflare context
539539
globalThis.caches = undefined;
540540
});
541541

542542
it("should not put the tags in the regional cache if the tags does not exists in the DO", async () => {
543543
const putMock = vi.fn();
544-
// @ts-expect-error - Defined on cloudfare context
544+
// @ts-expect-error - Defined on cloudflare context
545545
globalThis.caches = {
546546
open: vi.fn().mockResolvedValue({
547547
put: putMock,
@@ -560,13 +560,13 @@ describe("DOShardedTagCache", () => {
560560

561561
expect(getTagDataMock).toHaveBeenCalledWith(["tag1"]);
562562
expect(putMock).not.toHaveBeenCalled();
563-
// @ts-expect-error - Defined on cloudfare context
563+
// @ts-expect-error - Defined on cloudflare context
564564
globalThis.caches = undefined;
565565
});
566566

567567
it("should put multiple tags in the regional cache", async () => {
568568
const putMock = vi.fn();
569-
// @ts-expect-error - Defined on cloudfare context
569+
// @ts-expect-error - Defined on cloudflare context
570570
globalThis.caches = {
571571
open: vi.fn().mockResolvedValue({
572572
put: putMock,
@@ -595,13 +595,13 @@ describe("DOShardedTagCache", () => {
595595
"http://local.cache/shard/tag-hard;shard-1?tag=tag2",
596596
expect.any(Response)
597597
);
598-
// @ts-expect-error - Defined on cloudfare context
598+
// @ts-expect-error - Defined on cloudflare context
599599
globalThis.caches = undefined;
600600
});
601601

602602
it("should put missing tag in the regional cache if `regionalCacheDangerouslyPersistMissingTags` is true", async () => {
603603
const putMock = vi.fn();
604-
// @ts-expect-error - Defined on cloudfare context
604+
// @ts-expect-error - Defined on cloudflare context
605605
globalThis.caches = {
606606
open: vi.fn().mockResolvedValue({
607607
put: putMock,
@@ -627,13 +627,13 @@ describe("DOShardedTagCache", () => {
627627
"http://local.cache/shard/tag-hard;shard-1?tag=tag1",
628628
expect.any(Response)
629629
);
630-
// @ts-expect-error - Defined on cloudfare context
630+
// @ts-expect-error - Defined on cloudflare context
631631
globalThis.caches = undefined;
632632
});
633633

634634
it("should not put missing tag in the regional cache if `regionalCacheDangerouslyPersistMissingTags` is false", async () => {
635635
const putMock = vi.fn();
636-
// @ts-expect-error - Defined on cloudfare context
636+
// @ts-expect-error - Defined on cloudflare context
637637
globalThis.caches = {
638638
open: vi.fn().mockResolvedValue({
639639
put: putMock,
@@ -656,7 +656,7 @@ describe("DOShardedTagCache", () => {
656656

657657
expect(getTagDataMock).toHaveBeenCalledWith(["tag1"]);
658658
expect(putMock).not.toHaveBeenCalled();
659-
// @ts-expect-error - Defined on cloudfare context
659+
// @ts-expect-error - Defined on cloudflare context
660660
globalThis.caches = undefined;
661661
});
662662
});

packages/cloudflare/src/cli/build/bundle-server.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,20 @@ export async function bundleServer(buildOpts: BuildOptions, projectOpts: Project
113113
// Apply updater updates, must be the last plugin
114114
updater.plugin,
115115
] as Plugin[],
116-
external: [
117-
"./middleware/handler.mjs",
118-
// Do not bundle og when it is not used
119-
...(useOg ? [] : ["next/dist/compiled/@vercel/og/index.edge.js"]),
120-
],
116+
external: ["./middleware/handler.mjs"],
121117
alias: {
118+
// When @vercel/og is not used, alias the edge entry to a throwing shim so the
119+
// dynamic `import("next/dist/compiled/@vercel/og/index.edge.js")` call site
120+
// emitted by Next.js does not drag the library (~800 KiB) and its
121+
// `resvg.wasm` (~1.4 MiB) into the Worker bundle.
122+
...(useOg
123+
? {}
124+
: {
125+
"next/dist/compiled/@vercel/og/index.edge.js": path.join(
126+
buildOpts.outputDir,
127+
"cloudflare-templates/shims/throw.js"
128+
),
129+
}),
122130
// Workers have `fetch` so the `node-fetch` polyfill is not needed
123131
"next/dist/compiled/node-fetch": path.join(buildOpts.outputDir, "cloudflare-templates/shims/fetch.js"),
124132
// Workers have builtin Web Sockets

0 commit comments

Comments
 (0)