#51693: fix: process undefined in ESM preload when contextIsolation is disabled
Description of Change
Fixes #46142.
When nodeIntegration and contextIsolation are both disabled, the Node
globals (process, Buffer, setImmediate, ...) were being removed from the
renderer's main world via a process.once('loaded', ...) listener. The
'loaded' event fires on the next tick after lib/renderer/init.ts returns,
which is before any async ESM preload script has finished executing — so by
the time the preload code ran, process was already gone and any access to
it threw ReferenceError. CJS preloads were unaffected because they ran
synchronously inside init.ts, before 'loaded' fired.
This change drops the 'loaded'-based deletion and instead runs it
explicitly in an onPreloadsLoaded callback that is invoked right before
appCodeLoaded() in both the ESM-preload path (via .finally(), so it
still runs even if a preload throws) and the no-ESM-preload path. The
deletion still happens after every preload (CJS or ESM) has had a chance
to use the Node globals, and still before the renderer's user-facing
scripts run — preserving the existing security boundary.
Checklist
- PR description included
- I have built and tested this PR
-
npm testpasses - tests are changed or added
- relevant API documentation, tutorials, and examples are updated and follow the documentation style guide
- PR release notes describe the change in a way relevant to app developers, and are capitalized, punctuated, and past tense.
Release Notes
Notes: Fixed an issue where process and other Node globals were undefined in ESM preload scripts when contextIsolation was disabled.
Backports
Semver Impact
Semantic Versioning helps users understand the impact of updates:
- Major (X.y.z): Breaking changes that may require code modifications
- Minor (x.Y.z): New features that maintain backward compatibility
- Patch (x.y.Z): Bug fixes that don't change the API
- None: Changes that don't affect using facing parts of Electron