Skip to content

Commit 09441ba

Browse files
committed
docs(webpack): document sandboxed preload default for 7.x
Preload scripts are compiled with the sandboxedPreload webpack target by default (Electron 20+ / Forge 7.x), which removes Node.js access. Add a "Preload scripts" section explaining this behavior change from 6.x and how to opt into full Node.js access via nodeIntegration or a preload-only entry point. Fixes electron/forge#3659 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J8emyk2ZfnUyZyQpfRBmYc
1 parent 7ed40ed commit 09441ba

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

config/plugins/webpack.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,71 @@ declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: string;
173173
{% endcode %}
174174
{% endhint %}
175175

176+
## Preload scripts
177+
178+
You can attach a preload script to any window entry point by setting the `preload` key on that entry point, as shown in the [plugin configuration](#plugin-configuration) example above:
179+
180+
```javascript
181+
{
182+
name: 'main_window',
183+
html: './src/renderer/index.html',
184+
js: './src/renderer/index.js',
185+
preload: {
186+
js: './src/preload.js'
187+
}
188+
}
189+
```
190+
191+
### Preload scripts are sandboxed by default
192+
193+
{% hint style="warning" %}
194+
This is a behavior change from Forge 6. If you are upgrading from 6.x, read this section carefully.
195+
{% endhint %}
196+
197+
Since [Electron 20](https://www.electronjs.org/blog/electron-20-0#renderers-sandboxed-by-default), renderer processes (and their preload scripts) are **sandboxed by default**. To match this, the webpack plugin compiles each preload script with the [`sandboxedPreload` webpack target](https://webpack.js.org/configuration/target/) by default.
198+
199+
A sandboxed preload script runs in a restricted environment: it does **not** have access to Node.js APIs such as `require`, `process`, or Node core modules. It can still use the [polyfilled subset of Node](https://www.electronjs.org/docs/latest/tutorial/sandbox#preload-scripts) that Electron exposes to sandboxed preloads (for example `electron`, and a limited version of `process`), which is enough to set up a [`contextBridge`](https://www.electronjs.org/docs/latest/api/context-bridge). This is the recommended, secure default for most apps.
200+
201+
If your preload script worked in Forge 6 by calling `require` or otherwise depending on full Node.js access, it will fail under the sandboxed default. You have two options:
202+
203+
#### Give the preload full Node.js access
204+
205+
The preload's webpack target is derived from the `nodeIntegration` value of the entry point it belongs to. When `nodeIntegration` is `true` (set either on the entry point or on `renderer.nodeIntegration`), the preload is compiled with the `electronPreload` target instead, which grants full Node.js access.
206+
207+
{% code title="Plugin configuration" %}
208+
```javascript
209+
{
210+
name: 'main_window',
211+
html: './src/renderer/index.html',
212+
js: './src/renderer/index.js',
213+
nodeIntegration: true, // preload is compiled with the `electronPreload` target
214+
preload: {
215+
js: './src/preload.js'
216+
}
217+
}
218+
```
219+
{% endcode %}
220+
221+
{% hint style="warning" %}
222+
Enabling `nodeIntegration` disables the sandbox for that window's renderer as well, which reduces the security of your application. Prefer keeping the sandbox enabled and exposing only what you need through the `contextBridge`.
223+
{% endhint %}
224+
225+
If you only need full Node.js access in the preload but want to keep it as a standalone entry (for example to attach it to a `<webview>`), you can declare a **preload-only entry point**. It takes a `name` and a `preload` object, and its `nodeIntegration` value controls the preload's webpack target independently of any window:
226+
227+
{% code title="Plugin configuration" %}
228+
```javascript
229+
{
230+
name: 'main_window_preload',
231+
nodeIntegration: true,
232+
preload: {
233+
js: './src/preload.js'
234+
}
235+
}
236+
```
237+
{% endcode %}
238+
239+
The generated global for this entry is derived from its `name` with the `_PRELOAD_WEBPACK_ENTRY` suffix — so the entry named `main_window_preload` above is exposed to the main process as `MAIN_WINDOW_PRELOAD_PRELOAD_WEBPACK_ENTRY`.
240+
176241
## Advanced configuration
177242

178243
### webpack-dev-server

0 commit comments

Comments
 (0)