Skip to content

Commit 80773ad

Browse files
enable getCloudflareContext to also work with next dev
1 parent af15fd1 commit 80773ad

File tree

6 files changed

+57
-15
lines changed

6 files changed

+57
-15
lines changed

examples/api/next.config.mjs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
/** @type {import('next').NextConfig} */
2-
const nextConfig = {};
2+
const nextConfig = {
3+
webpack: (config) => {
4+
config.externals = ["wrangler"];
5+
return config;
6+
},
7+
};
38

49
export default nextConfig;

examples/api/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
"dependencies": {
1717
"next": "catalog:",
1818
"react": "catalog:",
19-
"react-dom": "catalog:"
19+
"react-dom": "catalog:",
20+
"wrangler": "catalog:"
2021
},
2122
"devDependencies": {
2223
"@opennextjs/cloudflare": "workspace:*",
2324
"@playwright/test": "catalog:",
24-
"@types/node": "catalog:",
25-
"wrangler": "catalog:"
25+
"@types/node": "catalog:"
2626
}
2727
}

packages/cloudflare/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,8 @@
4848
},
4949
"dependencies": {
5050
"ts-morph": "catalog:"
51+
},
52+
"peerDependencies": {
53+
"wrangler": "catalog:"
5154
}
5255
}

packages/cloudflare/src/api/get-cloudflare-context.ts

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,46 @@ export async function getCloudflareContext<
3737
CfProperties extends Record<string, unknown> = IncomingRequestCfProperties,
3838
Context = ExecutionContext,
3939
>(): Promise<CloudflareContext<CfProperties, Context>> {
40-
const cloudflareContext = (
41-
globalThis as unknown as {
42-
[cloudflareContextSymbol]: CloudflareContext<CfProperties, Context> | undefined;
43-
}
44-
)[cloudflareContextSymbol];
40+
const global = globalThis as unknown as {
41+
[cloudflareContextSymbol]: CloudflareContext<CfProperties, Context> | undefined;
42+
};
43+
44+
const cloudflareContext = global[cloudflareContextSymbol];
4545

4646
if (!cloudflareContext) {
47-
// TODO: cloudflareContext should always be present in production/preview, if not it means that this
48-
// is running under `next dev`, in this case use `getPlatformProxy` to return local proxies
49-
throw new Error("Cloudflare context is not defined!");
47+
// the cloudflare context is initialized by the worker and is always present in production/preview,
48+
// so, it not being present means that the application is running under `next dev`
49+
return getCloudflareContextInNextDev();
5050
}
5151

5252
return cloudflareContext;
5353
}
54+
55+
const cloudflareContextInNextDevSymbol = Symbol.for("__next-dev/cloudflare-context__");
56+
57+
/**
58+
* Gets a local proxy version of the cloudflare context (created using `getPlatformProxy`) when
59+
* running in the standard next dev server (via `next dev`)
60+
*
61+
* @returns the local proxy version of the cloudflare context
62+
*/
63+
async function getCloudflareContextInNextDev<
64+
CfProperties extends Record<string, unknown> = IncomingRequestCfProperties,
65+
Context = ExecutionContext,
66+
>(): Promise<CloudflareContext<CfProperties, Context>> {
67+
const global = globalThis as unknown as {
68+
[cloudflareContextInNextDevSymbol]: CloudflareContext<CfProperties, Context> | undefined;
69+
};
70+
71+
if (!global[cloudflareContextInNextDevSymbol]) {
72+
const { getPlatformProxy } = await import("wrangler");
73+
const { env, cf, ctx } = await getPlatformProxy();
74+
global[cloudflareContextInNextDevSymbol] = {
75+
env,
76+
cf: cf as unknown as CfProperties,
77+
ctx: ctx as Context,
78+
};
79+
}
80+
81+
return global[cloudflareContextInNextDevSymbol]!;
82+
}

packages/cloudflare/tsup.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const cliConfig = defineConfig({
88
format: ["esm"],
99
platform: "node",
1010
external: ["esbuild"],
11+
clean: true,
1112
onSuccess: async () => {
1213
await cp(`${__dirname}/src/cli/templates`, `${__dirname}/dist/cli/templates`, {
1314
recursive: true,
@@ -22,6 +23,7 @@ const apiConfig = defineConfig({
2223
format: ["esm"],
2324
platform: "node",
2425
external: ["server-only"],
26+
clean: true,
2527
});
2628

2729
export default [cliConfig, apiConfig];

pnpm-lock.yaml

Lines changed: 6 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)