Skip to content

Commit 936eb1e

Browse files
committed
fix: apply process.env override in ESM run mode, detect already-transformed CJS entries
1 parent cf23f90 commit 936eb1e

1 file changed

Lines changed: 20 additions & 11 deletions

File tree

packages/nodejs/src/execution-driver.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,8 +1048,12 @@ export class NodeExecutionDriver implements RuntimeDriver {
10481048
// large dependency trees (e.g., PI has hundreds of @sinclair/typebox
10491049
// sub-modules). CJS mode uses the in-process require-setup transform
10501050
// which is orders of magnitude faster.
1051-
const sessionMode = options.mode === "run" || entryIsEsm ? "run" : "exec";
1052-
const userCode = entryIsEsm
1051+
// If the code was already CJS-transformed by _resolveEntry (has the
1052+
// require-esm marker), use exec mode so require() and __dirname work.
1053+
const REQUIRE_ESM_MARKER = "/*__secure_exec_require_esm__*/";
1054+
const alreadyTransformed = options.code.startsWith(REQUIRE_ESM_MARKER);
1055+
const sessionMode = alreadyTransformed ? "exec" : (options.mode === "run" || entryIsEsm ? "run" : "exec");
1056+
const userCode = entryIsEsm && !alreadyTransformed
10531057
? options.code
10541058
: (() => {
10551059
const transformed = transformSourceForRequireSync(
@@ -1285,6 +1289,7 @@ export class NodeExecutionDriver implements RuntimeDriver {
12851289
this._currentSession = session;
12861290

12871291
// Execute in V8 session
1292+
console.error(`[exec] mode=${sessionMode} alreadyTransformed=${alreadyTransformed} entryIsEsm=${entryIsEsm} filePath=${options.filePath} codeLen=${userCode.length}`);
12881293
const result = await session.execute({
12891294
bridgeCode,
12901295
postRestoreScript,
@@ -1537,7 +1542,19 @@ function buildPostRestoreScript(
15371542
parts.push(getIsolateRuntimeSource("applyTimingMitigationOff"));
15381543
}
15391544

1540-
// Apply execution overrides (env, cwd, stdin) for exec mode
1545+
// Apply env, cwd, and stdin overrides for all modes.
1546+
// These must run even in "run" (ESM) mode so that process.env and
1547+
// process.cwd() reflect the spawn-time configuration.
1548+
if (processConfig.env) {
1549+
parts.push(`globalThis.__runtimeProcessEnvOverride = ${JSON.stringify(processConfig.env)};`);
1550+
parts.push(getIsolateRuntimeSource("overrideProcessEnv"));
1551+
}
1552+
if (processConfig.cwd) {
1553+
parts.push(`globalThis.__runtimeProcessCwdOverride = ${JSON.stringify(processConfig.cwd)};`);
1554+
parts.push(getIsolateRuntimeSource("overrideProcessCwd"));
1555+
}
1556+
1557+
// CJS file globals (__filename, __dirname, module) only for exec mode.
15411558
if (mode === "exec") {
15421559
const commonJsFileConfig = (() => {
15431560
if (filePath) {
@@ -1554,14 +1571,6 @@ function buildPostRestoreScript(
15541571
}
15551572
return null;
15561573
})();
1557-
if (processConfig.env) {
1558-
parts.push(`globalThis.__runtimeProcessEnvOverride = ${JSON.stringify(processConfig.env)};`);
1559-
parts.push(getIsolateRuntimeSource("overrideProcessEnv"));
1560-
}
1561-
if (processConfig.cwd) {
1562-
parts.push(`globalThis.__runtimeProcessCwdOverride = ${JSON.stringify(processConfig.cwd)};`);
1563-
parts.push(getIsolateRuntimeSource("overrideProcessCwd"));
1564-
}
15651574
if (bridgeConfig.stdin !== undefined) {
15661575
parts.push(`globalThis.__runtimeStdinData = ${JSON.stringify(bridgeConfig.stdin)};`);
15671576
parts.push(getIsolateRuntimeSource("setStdinData"));

0 commit comments

Comments
 (0)