Skip to content

Commit aca37dd

Browse files
committed
fix: wrap ESM overlay entries in CJS transform to avoid slow V8 ESM IPC resolver
1 parent e1fc3d1 commit aca37dd

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

packages/nodejs/src/kernel-runtime.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,17 @@ class NodeRuntimeDriver implements RuntimeDriver {
900900
if (hostPath) {
901901
try {
902902
const content = readFileSync(hostPath, 'utf-8');
903+
// Check if this is an ESM module. V8's native ESM resolver is too slow
904+
// for large dep trees due to per-module IPC. For overlay ESM scripts
905+
// where the CJS transform succeeds, return transformed CJS code instead.
906+
if (this._isOverlayEsmEntry(hostPath)) {
907+
const transformed = transformSourceForRequireSync(content, scriptPath);
908+
if (transformed !== content) {
909+
// Transform succeeded: use CJS version (fast in-process require)
910+
return { code: transformed, filePath: scriptPath };
911+
}
912+
// Transform failed: fall through to raw ESM (slow but correct)
913+
}
903914
return { code: content, filePath: scriptPath };
904915
} catch {
905916
// Fall through to the error below
@@ -913,4 +924,25 @@ class NodeRuntimeDriver implements RuntimeDriver {
913924
// No script or -e flag — read from stdin (not supported yet)
914925
throw new Error('node: missing script argument (stdin mode not supported)');
915926
}
927+
928+
/**
929+
* Check if a host filesystem path points to an ESM module by reading
930+
* the nearest package.json for "type": "module". Used to decide whether
931+
* to wrap overlay entry scripts in a CJS require() call.
932+
*/
933+
private _isOverlayEsmEntry(hostPath: string): boolean {
934+
let dir = dirname(hostPath);
935+
for (let i = 0; i < 10; i++) {
936+
const pkgJsonPath = join(dir, 'package.json');
937+
try {
938+
const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
939+
return pkg.type === 'module';
940+
} catch {
941+
const parent = dirname(dir);
942+
if (parent === dir) break;
943+
dir = parent;
944+
}
945+
}
946+
return false;
947+
}
916948
}

0 commit comments

Comments
 (0)