Webpack Plugin
Transform and bundle code for your Electron Forge app with webpack.
Last updated
Was this helpful?
Transform and bundle code for your Electron Forge app with webpack.
Last updated
Was this helpful?
This plugin makes it easy to set up standard tooling to compile both your main process code and your renderer process code, with built-in support for in the renderer process and support for multiple renderers.
You must provide two webpack configuration files: one for the main process in mainConfig
, and one for the renderer process in renderer.config
. The complete config options are available in the API docs under .
For example, this is the taken from Forge's :
This plugin generates a separate entry for the main process, as well as each renderer process and preload script.
You need to do two things in your project files in order to make this plugin work.
First, your main
entry in your package.json
file needs to point at "./.webpack/main"
like so:
Second, all loadURL
and preload
paths need to reference the magic global variables that this plugin will define for you.
Each entry point has two globals defined based on the name assigned to your entry point:
The renderer's entry point will be suffixed with _WEBPACK_ENTRY
The renderer's preload script will be suffixed with _PRELOAD_WEBPACK_ENTRY
In the case of the main_window
entry point in the earlier example, the global variables will be named MAIN_WINDOW_WEBPACK_ENTRY
and MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY
. An example of how to use them is given below:
These variables are only defined in the main process. If you need to use one of these paths in a renderer (e.g. to pass a preload script to a <webview>
tag), you can pass the magic variable value with a synchronous IPC round trip.
In development mode, you can change most webpack-dev-server
options by setting devServer
in your Forge Webpack plugin configuration.
Electron Forge monkeypatches the asset relocator loader in order for it to work with Electron properly, so the version has been pinned to ensure compatibility. If you upgrade that version, you do so at your own risk.
This creates a unique environment that requires additional webpack configuration.
When nodeIntegration
is true, the target
is electron-renderer
.
When nodeIntegration
is false, the target
is web
.
This option is false by default**.** You can set this option for all renderers via the renderer.nodeIntegration
option, and you can override its value in each renderer you create in the entryPoints
array.
In the below configuration example, webpack will compile to the electron-renderer
target for all entry points except for media_player
, which will compile to the web
target.
It is important that you enable nodeIntegration
in both in the main process code and the webpack plugin configuration. This option duplication is necessary because webpack targets are fixed upon compilation, but BrowserWindow's web preferences are determined on run time.
However, it is impossible for HMR to work inside preload scripts. However, webpack is constantly watching and recompiling those files so reload the renderer to get updates for preload scripts.
For the main process, type rs
in the console you launched electron-forge
from and Forge will restart your app for you with the new main process code.
When using Webpack 5 caching, asset permissions need to be maintained through their own cache, and the public path needs to be injected into the build.
To insure these cases work out, make sure to run initAssetCache
in the build, with the options.outputAssetBase
argument:
Here's a usage example in TypeScript with App
being the topmost component in a React component tree:
You can use this pattern in any other components depending on what you want to reload. For example, if you use the hot()
HOC for an AppBar
component and make a change to a child of AppBar
, then the entire AppBar
gets reloaded, but the higher-level App
layout remains otherwise unchanged. In essence, a change will propagate up to the first hot()
HOC found in a component tree.
In theory, you shouldn't need to care. In development, we spin up webpack-dev-server
instances to power your renderer processes. In production, we just build the static files.
Assuming you use the defined globals we explained in the above section, everything should work when your app is packaged.
Forge's webpack plugin uses to help you quickly iterate on renderer process code in development mode. Running electron-forge start
with the webpack plugin active will launch a dev server that is configurable through the plugin config.
In development mode, you can set a by setting devContentSecurityPolicy
in your Forge Webpack plugin configuration.
If you wish to use source maps in development, you'll need to set 'unsafe-eval'
for the directive. Using 'unsafe-eval'
will cause Electron itself to trigger a warning in the DevTools console about having that value enabled, which is usually fine so long as you do not set that value in production.
If you used the or templates to create your application, native modules will mostly work out of the box.
If you are setting up the plugin manually, you can make native modules work by adding the following two loaders to your module.rules
configuration in your Webpack config. Ensure you install both and as development dependencies.
If the asset relocator loader does not work for your native module, you may want to consider using webpack's .
In Electron, you can enable Node.js in the renderer process with . Renderers with the following options enabled will have a browser-like web environment with access to Node.js and all of its core APIs:
Webpack have first-class support for various Electron environments. Forge's webpack plugin will set the compilation target for renderers based on the nodeIntegration
option in the config:
In development mode, all your renderer processes in development will have enabled by default thanks to webpack-dev-server
.
If you're using React components, you may want to have HMR automatically pick up a change and reload the component without having to manually refresh the page. This is possible by installing to define which modules should be hot reloaded.
If you want to use something like to do virtual routing in your app, you will need to ensure you use a history method that is not based on the browser history APIs. Browser history will work in development but not in production, as your code will be loaded from the filesystem, not a web server. In the react-router
case, you should use the to make everything work.