尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

webpack 5 如何以 target 为 electron 构建主进程与渲染进程代码

webpack 5 如何以 target 为 electron 构建主进程与渲染进程代码 webpack 5 如何以 target 为 electron 构建主进程与渲染进程代码【免费下载链接】webpackA bundler for javascript and friends. Packs many modules into a few bundled assets. Code Splitting allows for loading parts of the application on demand. Through loaders, modules can be CommonJs, AMD, ES6 modules, CSS, Images, JSON, Coffeescript, LESS, ... and your custom stuff.项目地址: https://gitcode.com/GitHub_Trending/web/webpack在把 JS 代码打进 Electron 应用时主进程和渲染进程里require(app)、require(ipc-renderer)这类 Electron 内置模块不能被打包进产物——它们在运行环境里由 Electron 提供应该保持为 external由运行时加载。webpack 5 通过target选项直接支持这个场景指定electron-main、electron-preload或electron-rendererwebpack 会自动启用对应的externalsPresets把该进程可用的内置模块按上下文分别外部化。本文说明如何为两个进程各配置一次构建以及产物应满足什么特征来验证配置生效。适用前提使用 webpack 5 打包一个同时包含主进程与渲染进程代码的 Electron 应用。渲染进程代码若使用了浏览器 APItarget 中还包含 web 语义这一点由 webpack 内部的目标解析决定见 lib/config/target.js 中electron[X[.Y]]-main/preload/renderer的定义web: context ! main即只有 main 上下文不带 web 环境preload/renderer 视为有 web 环境。target 的三个取值与进程上下文在 lib/config/target.js 中target 的格式为electron[X[.Y]]-main/preload/renderer其中X.Y是可选的 Electron 版本号。格式描述为 Electron in version X.Y. Script is running in main, preload resp. renderer context.。常用取值target含义electron-main脚本运行在 Electron 主进程electron-preload脚本运行在 preload 脚本electron-renderer脚本运行在渲染进程node integrationelectron30-main同上但额外声明 Electron 版本号为 30用于按版本裁剪环境特性target 字符串中的版本号会映射到一组环境能力例如 lib/config/target.js 中给出的版本相关能力Electron 15 起 Node 核心模块可带node:前缀nodePrefixForCoreModules: v(15)、Electron 11 起支持动态import()dynamicImport: v(11)、Electron 28 起支持 ESMmodule: v(28)、Electron 12 起渲染进程支持顶层 await 等。这些值决定了 webpack 为该版本生成代码时允许使用哪些语法特性。webpack 如何自动外部化 Electron 内置模块target含 electron 时lib/config/defaults.js 会自动推导externalsPresetselectron总为 trueelectronMain/electronPreload/electronRenderer分别由 target 中的上下文决定见 lib/config/defaults.js。这三个 preset 的官方描述来自 schemas/WebpackOptions.jsonelectron把 main 和 preload 上下文共有的内置模块如electron、ipc、shell当作 external用require()加载electronMain把 main 上下文可用的内置模块如app、ipc-main、shell当作 externalelectronPreload把 preload 上下文可用的内置模块如web-frame、ipc-renderer、shell当作 externalelectronRenderer把 renderer 上下文可用的内置模块如web-frame、ipc-renderer、shell当作 external。具体外部化的模块清单在 lib/electron/ElectronTargetPlugin.js 中定义共享模块SHARED_MODULESclipboard、crash-reporter、electron、ipc、native-image、original-fs、screen、shell主进程模块MAIN_MODULESapp、auto-updater、browser-window、content-tracing、dialog、global-shortcut、ipc-main、menu、menu-item、power-monitor、power-save-blocker、protocol、session、tray、web-contents渲染进程模块RENDERER_MODULESdesktop-capturer、ipc-renderer、remote、web-frame。也就是说用electron-main构建时app、ipc-main等会保持为 external而ipc-renderer不会被外部化用electron-renderer构建时则相反。如果只写electron而不带-main等上下文后缀则只启用共享模块的外部化lib/WebpackOptionsApply.js 中当三个细粒度 preset 都未启用时传入undefined上下文只外部化 SHARED_MODULES。配置示例主进程与渲染进程的上下文不同需要用两套 target。下面是一个完整的webpack.config.js示例const path require(path); /** type {import(webpack).Configuration} */ module.exports [ { // 主进程 target: electron-main, entry: { main: path.resolve(__dirname, src/main.js), }, output: { path: path.resolve(__dirname, dist), filename: [name].js, }, }, { // 渲染进程 target: electron-renderer, entry: { renderer: path.resolve(__dirname, src/renderer.js), }, output: { path: path.resolve(__dirname, dist), filename: [name].js, }, }, ];示例中的src/main.js、src/renderer.js与输出目录dist是占位路径替换为你项目里实际的入口文件与输出位置。src/main.js里可以const { app, ipcMain } require(electron)src/renderer.js里可以const { ipcRenderer } require(electron)——这些引用都会按上文的清单外部化而不是被打包。如果应用还有 preload 脚本可以加第三个配置对象target 用electron-preload配置结构与上面一致。如果你的项目对 Electron 版本有明确下限也可以把 target 写成带版本号的形式如electron30-mainwebpack 会据此生成该版本支持的语法例如顶层 await 只在 Electron 12 的渲染进程产物中可用。执行构建npx webpack --config webpack.config.jsnpx会调用项目node_modules中的 webpack CLI前提是已在项目内安装 webpack如yarn add -D webpack webpack-cli或npm i -D webpack webpack-cli。多配置数组下webpack 会依次为 main 和 renderer 生成构建产物落在各自配置的output.path中。验证产物构建完成后验证方式是对照 lib/electron/ElectronTargetPlugin.js 与 schemas/WebpackOptions.json 中external require()加载的说明来检查产物在产物文件中检索被外部化模块的引用形式。以 main 产物为例源码中的require(electron)、require(app)、require(ipc-main)应原样保留为require(...)调用而不是被替换为打包进来的模块实现renderer 产物中require(electron)、require(ipc-renderer)同理。检查产物中不包含这些内置模块的实现代码。例如 main 产物中不应出现browser-window、session等模块的实现它们只应以 external 依赖的形式出现在产物里。用stats检查 external 依赖运行构建时 webpack 的 stats 输出会把require(app)这类模块列为 external也可以用npx webpack --config webpack.config.js --json stats.json导出 JSON检索其中 external 条目是否覆盖你代码中用到的内置模块名。反向检查在 renderer 产物中require(app)这种主进程模块不会被外部化它不在 RENDERER_MODULES 清单里如果你的渲染代码误引用了主进程模块说明代码放错了上下文而不是 webpack 配置问题。关于 ESM 输出的一个警告webpack 5 还支持output.moduleESM 输出。当output.module启用且 target 的 Electron 版本支持 ESM 时内置模块会以外部的module-import形式加载若output.module启用但 target 对应的 Electron 版本不支持 ESMwebpack 会降级为node-commonjs并在产物中追加一条编译警告原文为output.module is enabled, but the targeted electron version does not support ECMAScript modules (added in electron 28). Electron built-in modules are externalized as node-commonjs.见 lib/WebpackOptionsApply.js。即 ESM 支持从 Electron 28 开始目标版本低于 28 时出现这条警告属于预期行为外部化类型仍按node-commonjs处理。构建时看到这条警告先确认你的 target 版本号是否写对如electron28-renderer再判断是否需要处理。边界与限制target 不带上下文后缀的electron只外部化共享模块清单主进程/渲染进程各自的模块清单不会生效要完整外部化必须使用-main/-preload/-renderer后缀lib/electron/ElectronTargetPlugin.js。preload 与 renderer 使用同一份 RENDERER_MODULES 清单lib/electron/ElectronTargetPlugin.js即 preload 产物中外部化的内置模块与 renderer 相同不含app等主进程模块。commonjs类别的引用即require无论外部化类型如何都会输出为node-commonjs这是为了在模块产物下保持require兼容性lib/electron/ElectronTargetPlugin.js。内置模块之外的 npm 依赖仍会被正常打包Electron 的外部化只针对上面列出的内置模块清单。完成上述配置与验证后main 与 renderer 两份产物即可分别被 Electron 主进程和渲染进程直接加载内置模块的 require 会在运行时由 Electron 解析。【免费下载链接】webpackA bundler for javascript and friends. Packs many modules into a few bundled assets. Code Splitting allows for loading parts of the application on demand. Through loaders, modules can be CommonJs, AMD, ES6 modules, CSS, Images, JSON, Coffeescript, LESS, ... and your custom stuff.项目地址: https://gitcode.com/GitHub_Trending/web/webpack创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表