Quasar CLI with Vite - @quasar/app-vite
问题
由于主线程(包括 preload 脚本)使用 Rolldown 打包,import.meta.env.dirname 和 import.meta.env.filename(以及类似的方式)在开发和生产环境中无法提供预期的值,尤其是在涉及绝对路径时。
dist-electron/UnPackaged/
electron-assets/
# /src-electron/electron-assets 原样复制
icons/
# Electron 应用图标
electron-main.js
electron-preload.cjs
...原样复制 /public 目录的内容
解决方案
Quasar CLI 提供了一个开箱即用的方案,通过 IPC 通信来引用文件,无论是开发环境还是生产环境都能正常工作。
注意以下部分:
import {
registerQuasarRuntime,
resolveElectronAssetsPath
} from '#q-app/electron/main'
async function createWindow() {
const mainWindow = new BrowserWindow({
icon: resolveElectronAssetsPath('icons/icon.png') // linux
// ...
})
// ...
}
app.whenReady().then(async () => {
await registerQuasarRuntime()
// ...
})content_paste
import { contextBridge } from 'electron'
import { quasarRuntime } from '#q-app/electron/preload'
// 你可以将暴露的属性名 'quasarRuntime' 改为任何你喜欢的名称
contextBridge.exposeInMainWorld('quasarRuntime', quasarRuntime)content_paste
注意我们向渲染进程暴露了一个 quasarRuntime 变量,这样就可以在渲染进程中通过 window.quasarRuntime 来引用它。
你可以自由选择暴露的变量名,也可以只暴露这个运行时的部分功能。只需从 #q-app/electron/preload 导入并调用 contextBridge.exposeInMainWorld() 即可。
electron-main 的 API
用法:
import {
registerQuasarRuntime,
resolveElectronAssetsPath
// ...
} from '#q-app/electron/main'content_paste
可导入的内容:
/**
* 解析 electron-assets 目录的路径,
* 自动适配开发或生产环境。
* @param args 要拼接到 electron-assets 基础路径的路径片段
* @returns 完整的解析路径
*/
export declare function resolveElectronAssetsPath(...args: string[]): string;
/**
* 运行时确定的 electron-assets 目录的解析路径
*/
export declare const electronAssetsDir: string;
/**
* 解析 public 目录的路径,
* 自动适配开发或生产环境。
* @param args 要拼接到 public 基础路径的路径片段
* @returns 完整的解析路径
*/
export declare function resolvePublicPath(...args: string[]): string;
/**
* 运行时确定的 public 目录的解析路径
*/
export declare const publicDir: string;
/**
* 注册 Quasar Electron 运行时的 IPC 处理器。
* 这允许 preload 脚本和渲染进程通过 `ipcRenderer.sendSync` 同步请求解析后的路径。
*/
export declare function registerQuasarRuntime(): Promise<void>;content_paste
electron-preload 的 API
用法:
import {
quasarRuntime
// ...
} from '#q-app/electron/preload'content_paste
可导入的内容:
/**
* 同步请求主进程解析 electron-assets 目录的路径。
* @param args 要拼接到 electron-assets 基础路径的路径片段
* @returns 完整的解析路径
*/
export declare function resolveElectronAssetsPath(...args: string[]): string;
/**
* 运行时确定的 electron-assets 目录的解析路径
*/
export declare const electronAssetsDir: string;
/**
* 同步请求主进程解析 public 目录的路径。
* @param args 要拼接到 public 基础路径的路径片段
* @returns 完整的解析路径
*/
export declare function resolvePublicPath(...args: string[]): string;
/**
* 运行时确定的 public 目录的解析路径
*/
export declare const publicDir: string;
/**
* 一个包含同步路径解析工具的对象。
*/
export declare const quasarRuntime: {
electronAssetsDir: string;
resolveElectronAssetsPath: typeof resolveElectronAssetsPath;
publicDir: string;
resolvePublicPath: typeof resolvePublicPath;
};content_paste
在渲染进程(/src)中使用
window.quasarRuntime.resolvePublicPath('my-file')content_paste
读写本地文件
使用 Electron 的一大好处是可以访问用户的文件系统,这使得读写本地文件成为可能。为了避免 Chromium 的限制以及误写应用内部文件,请务必使用 Electron 的 API,特别是 app.getPath(name) 函数。这个辅助方法可以获取系统目录的文件路径,如用户桌面、系统临时文件目录等。
我们可以使用 userData 目录,它是专门为我们的应用保留的,因此可以确信其他程序或用户操作不会篡改这个文件空间。
注意,如果你关心安全性,你需要使用 IPC 通信在 preload 或渲染进程中处理文件操作,就像 Quasar CLI 的 quasarRuntime 所做的那样。