Skip to content

Commit e4d934e

Browse files
committed
Sync with latest @opennextjs/aws
1 parent 0702d2e commit e4d934e

30 files changed

+968
-2112
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { unstable_cache } from "next/cache";
2+
3+
async function getTime() {
4+
return new Date().toISOString();
5+
}
6+
7+
const cachedTime = unstable_cache(getTime, { revalidate: false });
8+
9+
export const revalidate = 10;
10+
11+
export default async function ISR() {
12+
const responseOpenNext = await fetch("https://opennext.js.org", {
13+
cache: "force-cache",
14+
});
15+
const dateInOpenNext = responseOpenNext.headers.get("date");
16+
const cachedTimeValue = await cachedTime();
17+
const time = getTime();
18+
return (
19+
<div>
20+
<h1>Date from from OpenNext</h1>
21+
<p data-testid="fetched-date">Date from from OpenNext: {dateInOpenNext}</p>
22+
<h1>Cached Time</h1>
23+
<p data-testid="cached-date">Cached Time: {cachedTimeValue}</p>
24+
<h1>Time</h1>
25+
<p data-testid="time">Time: {time}</p>
26+
</div>
27+
);
28+
}

examples/e2e/app-router/e2e/isr.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,31 @@ test("headers", async ({ page }) => {
6161
await page.reload();
6262
}
6363
});
64+
65+
test("Incremental Static Regeneration with data cache", async ({ page }) => {
66+
test.setTimeout(45000);
67+
await page.goto("/isr-data-cache");
68+
69+
const originalFetchedDate = await page.getByTestId("fetched-date").textContent();
70+
const originalCachedDate = await page.getByTestId("cached-date").textContent();
71+
const originalTime = await page.getByTestId("time").textContent();
72+
await page.reload();
73+
74+
let finalTime = originalTime;
75+
let finalCachedDate = originalCachedDate;
76+
let finalFetchedDate = originalFetchedDate;
77+
78+
// Wait 10 + 1 seconds for ISR to regenerate time
79+
await page.waitForTimeout(11000);
80+
do {
81+
await page.waitForTimeout(2000);
82+
finalTime = await page.getByTestId("time").textContent();
83+
finalCachedDate = await page.getByTestId("cached-date").textContent();
84+
finalFetchedDate = await page.getByTestId("fetched-date").textContent();
85+
await page.reload();
86+
} while (originalTime === finalTime);
87+
88+
expect(originalTime).not.toEqual(finalTime);
89+
expect(originalCachedDate).toEqual(finalCachedDate);
90+
expect(originalFetchedDate).toEqual(finalFetchedDate);
91+
});

packages/cloudflare/package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,10 @@
7171
"vitest": "catalog:"
7272
},
7373
"dependencies": {
74-
"@ast-grep/napi": "^0.36.1",
7574
"@dotenvx/dotenvx": "catalog:",
76-
"@opennextjs/aws": "https://pkg.pr.new/@opennextjs/aws@778",
75+
"@opennextjs/aws": "https://pkg.pr.new/@opennextjs/aws@790",
7776
"enquirer": "^2.4.1",
78-
"glob": "catalog:",
79-
"yaml": "^2.7.0"
77+
"glob": "catalog:"
8078
},
8179
"peerDependencies": {
8280
"wrangler": "catalog:"

packages/cloudflare/src/cli/build/build.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ export async function build(
9292
}
9393

9494
function ensureNextjsVersionSupported(options: buildHelper.BuildOptions) {
95-
if (buildHelper.compareSemver(options.nextVersion, "14.0.0") < 0) {
96-
logger.error("Next.js version unsupported, please upgrade to version 14 or greater.");
95+
if (buildHelper.compareSemver(options.nextVersion, "<", "14.2.0")) {
96+
logger.error("Next.js version unsupported, please upgrade to version 14.2 or greater.");
9797
process.exit(1);
9898
}
9999
}

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

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,15 @@ import path from "node:path";
44
import { fileURLToPath } from "node:url";
55

66
import { type BuildOptions, getPackagePath } from "@opennextjs/aws/build/helper.js";
7-
import { build } from "esbuild";
7+
import { ContentUpdater } from "@opennextjs/aws/plugins/content-updater.js";
8+
import { build, type Plugin } from "esbuild";
89

910
import { patchVercelOgLibrary } from "./patches/ast/patch-vercel-og-library.js";
1011
import { patchWebpackRuntime } from "./patches/ast/webpack-runtime.js";
1112
import * as patches from "./patches/index.js";
1213
import { inlineBuildId } from "./patches/plugins/build-id.js";
13-
import { ContentUpdater } from "./patches/plugins/content-updater.js";
1414
import { inlineDynamicRequires } from "./patches/plugins/dynamic-requires.js";
1515
import { inlineEvalManifest } from "./patches/plugins/eval-manifest.js";
16-
import { patchFetchCacheSetMissingWaitUntil } from "./patches/plugins/fetch-cache-wait-until.js";
1716
import { inlineFindDir } from "./patches/plugins/find-dir.js";
1817
import { patchInstrumentation } from "./patches/plugins/instrumentation.js";
1918
import { inlineLoadManifest } from "./patches/plugins/load-manifest.js";
@@ -68,7 +67,7 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {
6867
const openNextServer = path.join(outputPath, packagePath, `index.mjs`);
6968
const openNextServerBundle = path.join(outputPath, packagePath, `handler.mjs`);
7069

71-
const updater = new ContentUpdater();
70+
const updater = new ContentUpdater(buildOpts);
7271

7372
const result = await build({
7473
entryPoints: [openNextServer],
@@ -95,16 +94,15 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {
9594
fixRequire(updater),
9695
handleOptionalDependencies(optionalDependencies),
9796
patchInstrumentation(updater, buildOpts),
98-
patchFetchCacheSetMissingWaitUntil(updater),
9997
inlineEvalManifest(updater, buildOpts),
10098
inlineFindDir(updater, buildOpts),
10199
inlineLoadManifest(updater, buildOpts),
102100
inlineBuildId(updater),
103101
patchDepdDeprecations(updater),
104102
patchNextMinimal(updater),
105-
// Apply updater updaters, must be the last plugin
103+
// Apply updater updates, must be the last plugin
106104
updater.plugin,
107-
],
105+
] as Plugin[],
108106
external: ["./middleware/handler.mjs"],
109107
alias: {
110108
// Note: it looks like node-fetch is actually not necessary for us, so we could replace it with an empty shim
@@ -119,7 +117,6 @@ export async function bundleServer(buildOpts: BuildOptions): Promise<void> {
119117
// Note: we apply an empty shim to next/dist/compiled/edge-runtime since (amongst others) it generated the following `eval`:
120118
// eval(getModuleCode)(module, module.exports, throwingRequire, params.context, ...Object.values(params.scopedContext));
121119
// which comes from https://github.com/vercel/edge-runtime/blob/6e96b55f/packages/primitives/src/primitives/load.js#L57-L63
122-
// QUESTION: Why did I encountered this but mhart didn't?
123120
"next/dist/compiled/edge-runtime": path.join(
124121
buildOpts.outputDir,
125122
"cloudflare-templates/shims/empty.js"
@@ -220,13 +217,6 @@ export async function updateWorkerBundledCode(
220217
"'require(this.middlewareManifestPath)'",
221218
(code) => patches.inlineMiddlewareManifestRequire(code, buildOpts),
222219
],
223-
[
224-
"`patchAsyncStorage` call",
225-
(code) =>
226-
code
227-
// TODO: implement for cf (possibly in @opennextjs/aws)
228-
.replace("patchAsyncStorage();", "//patchAsyncStorage();"),
229-
],
230220
[
231221
"`require.resolve` call",
232222
// workers do not support dynamic require nor require.resolve

packages/cloudflare/src/cli/build/open-next/createServerBundle.ts

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,38 @@ import { copyTracedFiles } from "@opennextjs/aws/build/copyTracedFiles.js";
1010
import { generateEdgeBundle } from "@opennextjs/aws/build/edge/createEdgeBundle.js";
1111
import * as buildHelper from "@opennextjs/aws/build/helper.js";
1212
import { installDependencies } from "@opennextjs/aws/build/installDeps.js";
13+
import type { CodePatcher } from "@opennextjs/aws/build/patch/codePatcher.js";
14+
import { applyCodePatches } from "@opennextjs/aws/build/patch/codePatcher.js";
15+
import {
16+
patchFetchCacheForISR,
17+
patchUnstableCacheForISR,
18+
} from "@opennextjs/aws/build/patch/patchFetchCacheISR.js";
19+
import { patchFetchCacheSetMissingWaitUntil } from "@opennextjs/aws/build/patch/patchFetchCacheWaitUntil.js";
1320
import logger from "@opennextjs/aws/logger.js";
1421
import { minifyAll } from "@opennextjs/aws/minimize-js.js";
22+
import type { ContentUpdater } from "@opennextjs/aws/plugins/content-updater.js";
1523
import { openNextEdgePlugins } from "@opennextjs/aws/plugins/edge.js";
1624
import { openNextExternalMiddlewarePlugin } from "@opennextjs/aws/plugins/externalMiddleware.js";
1725
import { openNextReplacementPlugin } from "@opennextjs/aws/plugins/replacement.js";
1826
import { openNextResolvePlugin } from "@opennextjs/aws/plugins/resolve.js";
1927
import type { FunctionOptions, SplittedFunctionOptions } from "@opennextjs/aws/types/open-next.js";
2028
import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js";
29+
import type { Plugin } from "esbuild";
2130

2231
import { normalizePath } from "../utils/index.js";
2332

24-
export async function createServerBundle(options: buildHelper.BuildOptions) {
33+
interface CodeCustomization {
34+
// These patches are meant to apply on user and next generated code
35+
additionalCodePatches?: CodePatcher[];
36+
// These plugins are meant to apply during the esbuild bundling process.
37+
// This will only apply to OpenNext code.
38+
additionalPlugins?: (contentUpdater: ContentUpdater) => Plugin[];
39+
}
40+
41+
export async function createServerBundle(
42+
options: buildHelper.BuildOptions,
43+
codeCustomization?: CodeCustomization
44+
) {
2545
const { config } = options;
2646
const foundRoutes = new Set<string>();
2747
// Get all functions to build
@@ -39,7 +59,7 @@ export async function createServerBundle(options: buildHelper.BuildOptions) {
3959
if (fnOptions.runtime === "edge") {
4060
await generateEdgeBundle(name, options, fnOptions);
4161
} else {
42-
await generateBundle(name, options, fnOptions);
62+
await generateBundle(name, options, fnOptions, codeCustomization);
4363
}
4464
});
4565

@@ -102,7 +122,8 @@ export async function createServerBundle(options: buildHelper.BuildOptions) {
102122
async function generateBundle(
103123
name: string,
104124
options: buildHelper.BuildOptions,
105-
fnOptions: SplittedFunctionOptions
125+
fnOptions: SplittedFunctionOptions,
126+
codeCustomization?: CodeCustomization
106127
) {
107128
const { appPath, appBuildOutputPath, config, outputDir, monorepoRoot } = options;
108129
logger.info(`Building server function: ${name}...`);
@@ -151,27 +172,37 @@ async function generateBundle(
151172
buildHelper.copyEnvFile(appBuildOutputPath, packagePath, outputPath);
152173

153174
// Copy all necessary traced files
154-
await copyTracedFiles({
175+
const { tracedFiles, manifests } = await copyTracedFiles({
155176
buildOutputPath: appBuildOutputPath,
156177
packagePath,
157178
outputDir: outputPath,
158179
routes: fnOptions.routes ?? ["app/page.tsx"],
159180
bundledNextServer: isBundled,
160181
});
161182

183+
const additionalCodePatches = codeCustomization?.additionalCodePatches ?? [];
184+
185+
await applyCodePatches(options, tracedFiles, manifests, [
186+
patchFetchCacheSetMissingWaitUntil,
187+
patchFetchCacheForISR,
188+
patchUnstableCacheForISR,
189+
...additionalCodePatches,
190+
]);
191+
162192
// Build Lambda code
163193
// note: bundle in OpenNext package b/c the adapter relies on the
164194
// "serverless-http" package which is not a dependency in user's
165195
// Next.js app.
166196

167197
const disableNextPrebundledReact =
168-
buildHelper.compareSemver(options.nextVersion, "13.5.1") >= 0 ||
169-
buildHelper.compareSemver(options.nextVersion, "13.4.1") <= 0;
198+
buildHelper.compareSemver(options.nextVersion, ">=", "13.5.1") ||
199+
buildHelper.compareSemver(options.nextVersion, "<=", "13.4.1");
170200

171201
const overrides = fnOptions.override ?? {};
172202

173-
const isBefore13413 = buildHelper.compareSemver(options.nextVersion, "13.4.13") <= 0;
174-
const isAfter141 = buildHelper.compareSemver(options.nextVersion, "14.1") >= 0;
203+
const isBefore13413 = buildHelper.compareSemver(options.nextVersion, "<=", "13.4.13");
204+
const isAfter141 = buildHelper.compareSemver(options.nextVersion, ">=", "14.1");
205+
const isAfter142 = buildHelper.compareSemver(options.nextVersion, ">=", "14.2");
175206

176207
const disableRouting = isBefore13413 || config.middleware?.external;
177208

@@ -182,6 +213,7 @@ async function generateBundle(
182213
deletes: [
183214
...(disableNextPrebundledReact ? ["applyNextjsPrebundledReact"] : []),
184215
...(disableRouting ? ["withRouting"] : []),
216+
...(isAfter142 ? ["patchAsyncStorage"] : []),
185217
],
186218
}),
187219
openNextReplacementPlugin({

packages/cloudflare/src/cli/build/patches/ast/patch-vercel-og-library.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import path from "node:path";
33

44
import type { BuildOptions } from "@opennextjs/aws/build/helper.js";
55
import { getPackagePath } from "@opennextjs/aws/build/helper.js";
6+
import { parseFile } from "@opennextjs/aws/build/patch/astCodePatcher.js";
67
import { globSync } from "glob";
78

8-
import { parseFile } from "./util.js";
99
import { patchVercelOgFallbackFont, patchVercelOgImport } from "./vercel-og.js";
1010

1111
type TraceInfo = { version: number; files: string[] };

packages/cloudflare/src/cli/build/patches/ast/util.spec.ts

Lines changed: 0 additions & 65 deletions
This file was deleted.

0 commit comments

Comments
 (0)