Webpack 插件
使用 webpack 转换和打包 Electron Forge 应用的代码。
此插件简化了设置标准 webpack 工具以编译主进程代码和渲染进程代码的过程,并内置支持渲染进程中的 热模块替换 (HMR) 以及对多个渲染器的支持。
安装
用法
插件配置
您必须提供两个 webpack 配置文件:一个用于主进程的 mainConfig
,另一个用于渲染进程的 renderer.config
。完整的配置选项可在 API 文档中找到,位于 WebpackPluginConfig
。
例如,这是 Forge 的 配置 中取自 webpack 模板 的配置。
项目文件
此插件为主进程以及每个渲染进程和预加载脚本生成单独的入口。
您需要在项目文件中执行两件事才能使此插件正常工作。
package.json
首先,您需要将 package.json
文件中的 main
入口指向 "./.webpack/main"
,如下所示
主进程代码
其次,所有 loadURL
和 preload
路径都需要引用此插件将为您定义的魔法全局变量。
每个入口点根据分配给您的入口点的名称定义了两个全局变量
渲染器的入口点将以
_WEBPACK_ENTRY
为后缀渲染器的预加载脚本将以
_PRELOAD_WEBPACK_ENTRY
为后缀
在前面示例中的 main_window
入口点的情况下,全局变量将分别命名为 MAIN_WINDOW_WEBPACK_ENTRY
和 MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY
。下面给出了如何使用它们的示例
这些变量仅在主进程中定义。如果您需要在渲染器中使用其中一个路径(例如,将预加载脚本传递给 <webview>
标签),您可以使用同步 IPC 往返传递魔法变量值。
与 TypeScript 一起使用
如果您将 webpack 插件与 TypeScript 一起使用,则需要手动声明这些魔法变量以避免编译器错误。
高级配置
webpack-dev-server
Forge 的 webpack 插件使用 webpack-dev-server
来帮助您在开发模式下快速迭代渲染进程代码。在启用 webpack 插件的情况下运行 electron-forge start
将启动一个开发服务器,该服务器可以通过插件配置进行配置。
devServer
在开发模式下,您可以通过在 Forge Webpack 插件配置中设置 devServer
来更改大多数 webpack-dev-server
选项。
devContentSecurityPolicy
在开发模式下,您可以通过在 Forge Webpack 插件配置中设置 devContentSecurityPolicy
来设置 内容安全策略 (CSP)。
如果您希望在开发中使用 源代码映射,则需要为 script-src
指令设置 'unsafe-eval'
。使用 'unsafe-eval'
将导致 Electron 本身在 DevTools 控制台中触发有关启用该值的警告,只要您 不要在生产环境中设置该值,这通常是可以的。
原生 Node 模块
如果您使用 Webpack 或 TypeScript + Webpack 模板创建应用程序,则原生模块大多可以开箱即用。
如果您手动设置插件,可以通过在 Webpack 配置文件中的 module.rules
配置中添加以下两个加载器来使原生模块工作。请确保您安装了 node-loader
和 @vercel/webpack-asset-relocator-loader
作为开发依赖项。
Electron Forge 对资产重定位加载器进行了猴子补丁,以便使其能够与 Electron 正确配合使用,因此版本已被固定以确保兼容性。如果您升级该版本,则需自行承担风险。
如果资产重定位加载器不适用于您的原生模块,您可能需要考虑使用 Webpack 的 externals 配置。
节点集成
在您的应用代码中启用节点集成
在 Electron 中,您可以使用 BrowserWindow
构造函数选项 在渲染器进程中启用 Node.js。启用以下选项的渲染器将拥有一个类似浏览器的 Web 环境,可以访问 Node.js 的 require
及其所有核心 API。
这创建了一个独特的环境,需要额外的 Webpack 配置。
在插件配置中设置正确的 Webpack 目标
Webpack 的 目标 对各种 Electron 环境提供了第一类支持。Forge 的 Webpack 插件将根据配置中的 nodeIntegration
选项设置渲染器的编译目标。
当
nodeIntegration
为 true 时,target
为electron-renderer
。当
nodeIntegration
为 false 时,target
为web
。
此选项默认情况下为 false。您可以通过 renderer.nodeIntegration
选项为所有渲染器设置此选项,并且可以在 entryPoints
数组中创建的每个渲染器中覆盖其值。
在下面的配置示例中,Webpack 将为除 media_player
之外的所有入口点编译到 electron-renderer
目标,media_player
将编译到 web
目标。
重要的是,您需要在主进程代码和 Webpack 插件配置中都启用 nodeIntegration
。此选项重复是必要的,因为 Webpack 目标在编译时是固定的,但 BrowserWindow 的 Web 首选项是在运行时确定的。
热模块替换
在开发模式下,由于 webpack-dev-server
,默认情况下,开发环境中的所有渲染器进程都将启用 热模块替换 (HMR)。
但是,HMR 无法在预加载脚本中工作。但是,Webpack 会持续监视和重新编译这些文件,因此重新加载渲染器以获取预加载脚本的更新。
对于主进程,在您启动 electron-forge
的控制台中键入 rs
,Forge 将使用新的主进程代码重新启动您的应用。
热重载缓存
使用 Webpack 5 缓存时,需要通过其自身的缓存维护资产权限,并将公共路径注入到构建中。
为了确保这些情况正常工作,请确保在构建中运行 initAssetCache
,并使用 options.outputAssetBase
参数。
React 的热重载
如果您使用 React 组件,您可能希望 HMR 自动获取更改并重新加载组件,而无需手动刷新页面。这可以通过安装 react-hot-loader
来定义哪些模块应该进行热重载来实现。
以下是在 TypeScript 中使用 App
作为 React 组件树中最高级组件的一个使用示例。
您可以根据需要在任何其他组件中使用此模式。例如,如果您对 AppBar
组件使用 hot()
HOC 并对 AppBar
的子组件进行更改,则整个 AppBar
将重新加载,但更高级别的 App
布局保持不变。从本质上讲,更改将传播到组件树中找到的第一个 hot()
HOC。
生产环境中会发生什么?
理论上,您不需要关心。在开发环境中,我们启动 webpack-dev-server
实例来为您的渲染器进程提供支持。在生产环境中,我们只需构建静态文件。
假设您使用了我们在上一节中解释的定义的全局变量,那么当您的应用被打包时,一切应该都能正常工作。
如何进行虚拟路由?
如果您想使用类似于react-router
的库在您的应用中进行虚拟路由,您需要确保使用的方法不依赖于浏览器的历史记录 API。浏览器历史记录在开发环境下可以正常工作,但在生产环境下则无法使用,因为您的代码将从文件系统加载,而不是从 Web 服务器加载。在react-router
的情况下,您应该使用MemoryRouter
来使一切正常工作。
上次更新于