Quasar Electron 应用开发入门:理解主进程、渲染进程与 Preload 桥接
前端UI组件跨平台【免费下载链接】quasarQuasar Framework - Build high-performance VueJS user interfaces in record time项目地址https://gitcode.com/gh_mirrors/qu/quasar点击查看免费下载Quasar Framework 通过quasar/app-vite提供了基于 Electron 的桌面应用开发模式让你可以用同一套 Vue 组件代码同时构建 Web 与跨平台桌面应用。本文以 Electron 技术介绍 为核心骨架结合仓库内真实模板与构建源码系统讲解 Electron 的多进程架构、Quasar 默认安全配置以及如何通过 preload 脚本安全地在 UI 与原生能力之间架起桥梁。读完本文你将掌握 Electron 模式的项目结构、进程职责划分以及编写安全 IPC 桥接的正确姿势。Electron 是什么Electron 是一个开源框架用于使用 JavaScript、HTML 和 CSS 构建跨平台桌面应用。它内嵌了 Chromium负责渲染界面和 Node.js提供原生系统能力因此 Quasar 应用能够把基于 Web 的界面与桌面原生能力结合起来——这正是 Quasar 的 Electron 模式Mode存在的意义一次编写 Vue 界面打包为 Windows、macOS、Linux 桌面程序。从 Electron 官方文档可知一个 Electron 应用通常会运行多个操作系统进程。Quasar 默认模板把这三类进程角色分得清清楚楚进程职责Quasar 中的位置主进程Main Process管理应用生命周期与原生窗口/src-electron/electron-main.js或.ts渲染进程Renderer Process用 Chromium 显示来自/src的 UI 代码/src普通 Quasar 前端代码Preload 脚本Preload Script在渲染内容加载前运行桥接受控 API/src-electron/electron-preload.js或.ts渲染进程Renderer Process渲染进程负责把 Quasar UI 代码展示给用户。Electron 使用 Chromium 在渲染进程中显示来自/src的 UI 代码。这一点对 Quasar 开发者非常友好你平时写的组件、路由、状态管理代码完全不需要改动它们照常运行在浏览器内核里。关键在于安全默认值Quasar 默认的 Electron 模板保持 Node.js 集成nodeIntegration关闭并开启上下文隔离contextIsolation。这意味着渲染进程里的网页代码无法直接访问 Node.js 或 Electron 的原生 API。当 UI 需要某个原生能力时正确的做法是使用 preload 桥接 IPC进程间通信。在仓库模板 app-vite/templates/electron/js/electron-main.js 中可以看到默认窗口的安全配置const mainWindow new BrowserWindow({ icon: resolveElectronAssetsPath(icons/icon.png), // Windows and Linux width: 1000, height: 600, useContentSize: true, webPreferences: { contextIsolation: true, // https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/electron-preload-script preload: path.join(import.meta.dirname, electron-preload.cjs) } })注意这里没有设置nodeIntegration: true这正是模板刻意为之的安全基线。主进程Main Process主进程运行的是包package的main入口负责管理应用生命周期、创建浏览器窗口。在 Quasar 项目中它的源码位于/src-electron/electron-main.jsTypeScript 项目为.ts对应模板 app-vite/templates/electron/ts/electron-main.ts。从默认模板可以看出主进程的核心工作流void app.whenReady().then(() { registerQuasarRuntime() createWindow() app.on(activate, () { if (BrowserWindow.getAllWindows().length 0) { createWindow() } }) }) app.on(window-all-closed, () { if (platform ! darwin) { app.quit() } })这里包含三个典型的 Electron 生命周期事件app.whenReady()应用就绪后注册 Quasar 运行时registerQuasarRuntime()它向渲染进程提供路径解析的 IPC handler并创建主窗口activatemacOS 上点击 Dock 图标且无窗口时重新建窗window-all-closed除 macOS 外所有窗口关闭即退出应用。主进程源码还展示了开发/生产环境的窗口加载差异app-vite/templates/electron/js/electron-main.jsif (import.meta.env.QUASAR_DEV) { await mainWindow.loadURL(import.meta.env.QUASAR_APP_URL) } else { await mainWindow.loadFile(index.html) } if (import.meta.env.QUASAR_DEBUG) { mainWindow.webContents.openDevTools() // 开发或带调试的生产构建 } else { mainWindow.webContents.on(devtools-opened, () { mainWindow.webContents.closeDevTools() // 生产环境禁止 DevTools }) }Preload 脚本Preload 脚本在渲染进程内容加载之前运行文件位于/src-electron/electron-preload.js或.ts。它的核心使命是使用 Electron 的contextBridge向 UI 暴露小而专的 API而不是把 Node.js 或 Electron 的完整 API 直接暴露给渲染进程。仓库的默认模板 app-vite/templates/electron/js/electron-preload.js 本身就是一个很好的示范import { contextBridge } from electron import { quasarRuntime } from #q-app/electron/preload contextBridge.exposeInMainWorld(quasarRuntime, quasarRuntime)模板文件头部的注释明确警告这也是官方安全建议preload 脚本运行在受限沙箱中不要在 preload 中直接importnode_modules 里的包或直接使用 Node.js API而应通过 IPC 把这些工作交给主进程完成。quasarRuntime是 Quasar 内置注入的运行时对象实现见 app-vite/exports/electron/preload-runtime.jsexport const quasarRuntime { electronAssetsDir: resolveElectronAssetsPath(), resolveElectronAssetsPath, publicDir: resolvePublicPath(), resolvePublicPath }这两个路径解析方法通过ipcRenderer.sendSync同步调用主进程注册的quasar-electron:resolve-electron-assets与quasar-electron:resolve-public通道见 app-vite/exports/electron/main-runtime.js从而让渲染进程安全地拿到src-electron/electron-assets与public目录的真实磁盘路径——这正是“受控 API”的体现。暴露你自己的桥接方法在生成的项目中/src-electron/electron-preload.js已经暴露了 Quasar 的运行时路径辅助方法你可以在此基础上添加自己的桥接方法。同时确保/src-electron/electron-main.js的webPreferences中配置了 preload默认模板已包含注意扩展名是.cjs这是有意为之// 在文件顶部添加 import path from node:path // ... function createWindow () { // ... const mainWindow new BrowserWindow({ // ... webPreferences: { // HERE IS THE MAGIC (notice .cjs - NOT a mistake): preload: path.join(import.meta.dirname, electron-preload.cjs) } }).cjs扩展名不是笔误从构建源码 app-vite/lib/modes/electron/electron-config.js 的注释可知preload 脚本会被编译为 CommonJS 格式因为 Electron 要求 ESM preload 脚本必须关闭沙箱而沙箱化 preload 只能以纯 JavaScript 运行关闭沙箱会带来安全风险。一个自定义 preload 的完整示例/** * 此文件专门用于安全目的 * 通过 Electron 的 contextBridge 将特权 API 安全暴露给渲染进程 * 并通过 IPC 与主进程通信。 * * WARNING! * preload 脚本沙箱对完整 Node.js 环境访问有限。 * 不要在此文件中直接 import node_modules 的包或直接使用 Node.js API * 应通过 IPC 与主进程通信在那里访问包与 Node.js 功能。 */ import { contextBridge } from electron import { quasarRuntime } from #q-app/electron/preload contextBridge.exposeInMainWorld(quasarRuntime, quasarRuntime)安全注意事项contextBridge 不等于安全仅仅使用contextBridge并不意味着你做的每件事都是安全的。例如下面的代码是不安全的// 坏代码不要这样做 contextBridge.exposeInMainWorld(myAPI, { send: ipcRenderer.send })它直接暴露了一个强大的 API 而没有做任何参数过滤这会让任何网页都能发送任意的 IPC 消息而这显然不是你想要的结果。正确的方式是为每条 IPC 消息提供一个专门的方法// 好代码 contextBridge.exposeInMainWorld(myAPI, { loadPreferences: () ipcRenderer.invoke(myAPI:load-prefs) })这样loadPreferences就可以在渲染进程代码中以window.myAPI.loadPreferences()的形式调用。[!WARNING] 为暴露的 API 选择名称时要避免与Window上已有的属性名冲突。对应的 IPC 处理逻辑写在主进程里ipcMain.handle(myAPI:load-prefs, () { return { // 包含偏好设置的对象 } })自定义主进程与 preload 脚本路径Quasar 允许你调整 Electron 相关文件的约定路径。在quasar.config文件中使用sourceFiles.electronMain修改主进程源码位置使用electron.preloadScripts配置一个或多个 preload 源文件——条目相对于/src-electron目录且省略扩展名sourceFiles: { electronMain: src-electron/electron-main }, electron: { preloadScripts: [ electron-preload, secondary-preload ] }从构建实现 app-vite/lib/modes/electron/electron-config.js 可以确认preloadScripts数组中的每个条目都会被依次编译主进程入口以 ESM 格式format: esm编译输出electron-main.jspreload 则以 CJS 格式format: cjs逐个编译为*.cjs文件且两者都会把electron标记为 external。这也解释了为什么webPreferences.preload必须指向.cjs文件。深入理解Quasar 是如何组织 Electron 模式的模式安装在项目中启用 Electron 模式后quasar dev -m electron与quasar build -m electron即可工作。模式安装逻辑见 app-vite/lib/modes/electron/electron-installation.js它会创建/src-electron目录根据项目是否使用 TypeScript 复制templates/electron/js或templates/electron/ts下的模板文件并把 Electron 版本写入src-electron/package.json的devDependencies。模板目录速览完整的 Electron 模板位于仓库 app-vite/templates/electroncommon/package.jsonsrc-electron独立包定义声明electron依赖common/electron-assets/icons/icon.icnsmacOS、icon.icoWindows、icon.png跨平台/开发态等应用图标js/electron-main.js、js/electron-preload.jsJavaScript 项目模板ts/electron-main.ts、ts/electron-preload.tsTypeScript 项目模板。运行时桥接的两端Quasar 把主进程侧与 preload 侧的运行时 API 分别封装为#q-app/electron/main与#q-app/electron/preload两个模块主进程侧 app-vite/exports/electron/main-runtime.js 提供registerQuasarRuntime()注册 IPC handler、resolveElectronAssetsPath()、resolvePublicPath()preload 侧 app-vite/exports/electron/preload-runtime.js 提供对应的quasarRuntime对象通过同步 IPC 获取路径。这样一来渲染进程里的 Quasar 代码始终只与window.quasarRuntime这一层薄薄的受控接口打交道原生能力全部收敛在主进程中构成了完整的安全闭环。小结Quasar 的 Electron 模式把“Web 界面”与“桌面原生”清晰地分层渲染进程负责 UI主进程负责生命周期与窗口preload 脚本负责在两者之间安全传话。牢记三个默认安全原则——关闭nodeIntegration、开启contextIsolation、通过contextBridge IPC 暴露最小化 API——你的 Quasar 桌面应用就能在获得原生能力的同时守住安全边界。更深入的主题IPC 全流程、文件系统访问、窗口定制、安全加固、TypeScript 支持等可以继续阅读同目录下的 electron-preload-script.md、electron-security-concerns.md 与 electron-with-typescript.md 等配套文档。赞分享前端UI组件跨平台【免费下载链接】quasarQuasar Framework - Build high-performance VueJS user interfaces in record time项目地址https://gitcode.com/gh_mirrors/qu/quasar点击查看免费下载相关推荐使用 Preload 脚本与 IPC 安全打通主进程与渲染进程Electron 官方教程三实战解读使用 Preload 脚本与 IPC 安全打通主进程与渲染进程Electron 官方教程三实战解读 本篇文章围绕 Electron 官方教程第三部分「使用桌面应用跨平台前端Deskreen进程管理机制Electron主进程与渲染进程通信Deskreen进程管理机制Electron主进程与渲染进程通信 1. Electron进程模型概述 Electron框架采用多进程架构主要包含 主进程M桌面应用音视频tsParticles Electron 桌面演示主进程、Preload 与渲染进程三层结构及构建运行全流程tsParticles Electron 桌面演示主进程、Preload 与渲染进程三层结构及构建运行全流程 本文以仓库中 demo/electron htt前端上一篇financial-services operations插件实战指南如何四步完成KYC文档解析与规则网格评估下一篇如何快速掌握进化分析PhyloSuite终极指南帮你轻松搞定系统发育研究创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考