我制作了一个小型电子应用,需要加载一个preload js文件。
当我使用electron .
启动应用时,它会找到该文件,但是当打包应用时,它不会。
此处致电:
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false,
nativeWindowOpen: true,
webSecurity: false,
preload: path.join(__dirname, 'preload.js')
}
})
我简化的package.json:
"name": "app",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"start": "electron .",
"build": "electron-packager . --platform=win32 --arch=x64 --overwrite"
}
"devDependencies": {
"electron": "^1.8.4",
"electron-packager": "^12.0.1",
}
我的项目结构:
- node_modules
- main.js
- preload.js
- package.json
我已经检查了path.join
的结果,在这两种情况下,路径都是正确的,文件就在那里。
答案 0 :(得分:3)
需要将预加载脚本指定为绝对路径。因此,这与您在开发中运行它和打包为asar文件形式运行它的时间有所不同。
const getSourceDirectory = () => isDev()
? path.join(process.cwd(), 'build', 'src') // or wherever your local build is compiled
: path.join(process.resourcesPath, 'app', 'src'); // asar location
const preload = path.resolve(getSourceDirectory(), 'preload.js');
答案 1 :(得分:1)
对于使用 Electron Forge webpack typescript 样板的人:
preload
文件中添加 package.json
键:{
"config": {
"forge": {
"plugins": [
[
"@electron-forge/plugin-webpack",
{
"mainConfig": "./webpack.main.config.js",
"renderer": {
"config": "./webpack.renderer.config.js",
"entryPoints": [
{
"html": "./src/index.html",
"js": "./src/renderer.tsx",
"name": "main_window",
"preload": {
"js": "./src/preload.ts"
}
}
]
}
}
]
]
}
}
}
预加载脚本可以是打字稿文件。
MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY
常量作为 preload
的值:// Tell typescript about this magic constant
declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: any;
// [...]
const mainWindow = new BrowserWindow({
height: 1000,
width: 1500,
webPreferences: {
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
}
});
preload.ts
中写:import {
contextBridge,
ipcRenderer
} from 'electron';
contextBridge.exposeInMainWorld(
'electron',
{
doThing: () => ipcRenderer.send('do-a-thing')
}
)
index.d.ts
文件,写入:declare global {
interface Window {
electron: {
doThing(): void;
}
}
}
启动您的应用,在您的开发控制台中输入 electron
并查看它的定义。
奖励:为 contextBridge 公开的 API 获得正确的输入:
为什么要分开?不确定是否需要,但我更喜欢不必从包含渲染器进程中的主进程代码(如 preload.ts)的文件中导入接口。
// exposed-main-api.model.ts
export interface ExposedMainAPI {
doThat(data: string): Promise<number>;
}
// index.d.ts
declare global {
interface Window {
electron: ExposedMainAPI
}
}
// preload.ts
import {
contextBridge,
ipcRenderer
} from 'electron';
const exposedAPI: ExposedAPI = {
// You are free to omit parameters typing and return type if you feel so.
// TS know the function type thanks to exposedAPI typing.
doThat: (data) => ipcRenderer.invoke('do-that-and-return-promise', data)
};
// note: this assume you have a `ipcMain.handle('do-thing-and-return-promise', ...)`
// somewhere that return a number.
contextBridge.exposeInMainWorld('electron', exposedAPI);
学分:
index.d.ts
输入和 contextBridge
的小示例用法:https://github.com/electron/electron/issues/9920#issuecomment-743803249另见: