Skip to content

Commit

Permalink
fix process.env not giving access to bindings during local developm…
Browse files Browse the repository at this point in the history
…ent (in `next-dev`) (#690)

---------

Co-authored-by: Pete Bacon Darwin <[email protected]>
  • Loading branch information
dario-piotrowicz and petebacondarwin authored Mar 7, 2024
1 parent 555b4a7 commit 9900517
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 42 deletions.
5 changes: 5 additions & 0 deletions .changeset/proud-coats-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cloudflare/next-on-pages': patch
---

fix `process.env` not giving access to bindings during local development (in `next-dev`)
106 changes: 64 additions & 42 deletions internal-packages/next-dev/src/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ const cloudflareRequestContextSymbol = Symbol.for(
'__cloudflare-request-context__',
);

const processEnvIsPatched = Symbol('PROCESS.ENV_IS_PATCHED');

const globalsArePatched = Symbol('GLOBALS_ARE_PATCHED');

type RuntimeContext = Record<string, unknown> & {
process?: { env?: Record<string | symbol, unknown> };
[cloudflareRequestContextSymbol]?: {
env: unknown;
ctx: unknown;
cf: unknown;
};
[globalsArePatched]?: boolean;
};

/**
* Next.js uses the Node.js vm module's `runInContext()` function to evaluate the edge functions
* in a runtime context that tries to simulate as accurately as possible the actual production runtime
Expand All @@ -21,56 +35,64 @@ export function monkeyPatchVmModule({ env, cf, ctx, caches }: PlatformProxy) {

const originalRunInContext = vmModule.runInContext.bind(vmModule);

vmModule.runInContext = (
...args: [
string,
Record<string, unknown> & {
process?: { env?: Record<string, unknown> };
[cloudflareRequestContextSymbol]?: {
env: unknown;
ctx: unknown;
cf: unknown;
};
},
...[unknown],
]
) => {
vmModule.runInContext = (...args: [string, RuntimeContext, ...unknown[]]) => {
const runtimeContext = args[1];

if (!runtimeContext[cloudflareRequestContextSymbol]) {
runtimeContext[cloudflareRequestContextSymbol] = {
env,
ctx,
cf,
};
if (runtimeContext.process?.env) {
for (const [name, binding] of Object.entries(env)) {
runtimeContext.process.env[name] = binding;
}
}
runtimeContext[cloudflareRequestContextSymbol] ??= {
env,
ctx,
cf,
};

runtimeContext['caches'] = caches;

runtimeContext['Request'] = new Proxy(Request, {
construct(target, args, newTarget) {
if (
args.length >= 2 &&
typeof args[1] === 'object' &&
args[1].duplex === undefined
) {
args[1].duplex = 'half';
}
return Reflect.construct(target, args, newTarget);
},
});
runtimeContext['Response'] = Response;
runtimeContext['Headers'] = Headers;
}
monkeyPatchProcessEnv(runtimeContext, env);
monkeyPatchAuxiliaryGlobals(runtimeContext, caches);

return originalRunInContext(...args);
};
}

function monkeyPatchProcessEnv(
runtimeContext: RuntimeContext,
env: Record<string, unknown>,
) {
if (
runtimeContext.process?.env &&
!runtimeContext.process.env[processEnvIsPatched]
) {
if (runtimeContext.process.env) {
for (const [name, binding] of Object.entries(env)) {
runtimeContext.process.env[name] = binding;
}
}
runtimeContext.process.env[processEnvIsPatched] = true;
}
}

function monkeyPatchAuxiliaryGlobals(
runtimeContext: RuntimeContext,
caches: PlatformProxy['caches'],
) {
if (!runtimeContext[globalsArePatched]) {
runtimeContext['caches'] = caches;
runtimeContext['Request'] = new Proxy(Request, {
construct(target, args, newTarget) {
if (
args.length >= 2 &&
typeof args[1] === 'object' &&
args[1].duplex === undefined
) {
args[1].duplex = 'half';
}
return Reflect.construct(target, args, newTarget);
},
});
runtimeContext['Response'] = Response;
runtimeContext['Headers'] = Headers;

runtimeContext[globalsArePatched] = true;
}
}

/**
* Next dev server imports the config file twice (in two different processes, making it hard to track),
* this causes the setup to run twice as well, to keep things clean and not allocate extra resources
Expand Down

0 comments on commit 9900517

Please sign in to comment.