我制作了一个需要加载预加载 js 文件的小型 Electron 应用程序.
I've made a small Electron app which needs to load a preload js file.
当我用 electron .
启动应用程序时,它会找到该文件,但是当应用程序被打包时,它不会.
When I start the app with electron .
, it finds the file, but when the app is packaged, it doesn't.
在此处拨打电话:
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false,
nativeWindowOpen: true,
webSecurity: false,
preload: path.join(__dirname, 'preload.js')
}
})
我的简化 package.json:
My simplified 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",
}
我的项目结构:
- 节点模块
- main.js
- preload.js
- preload.js
- package.json
- package.json
我检查了 path.join
的结果,在这两种情况下,路径都是正确的,并且文件在那里.
I've checked the result of the path.join
and in both cases, the path is correct, and the file is there.
对于使用 Electron Forge webpack typescript 样板的人们:
For peoples using Electron Forge webpack typescript boilerplate :
package.json
文件中添加 preload
键:preload
key in package.json
file:{
"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"
}
}
]
}
}
]
]
}
}
}
预加载脚本可以是打字稿文件.
Preload script can be a typescript file.
MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY
常量作为 preload
的值:MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY
constant as value for 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
文件,写入:index.d.ts
file, write :declare global {
interface Window {
electron: {
doThing(): void;
}
}
}
启动您的应用程序,在您的开发控制台中您可以输入 electron
并查看它的定义.
奖励:为 contextBridge 公开的 API 正确输入:
BONUS: getting the typing right for the contextBridge exposed API:
为什么要分开 fie ?不确定是否需要,但我不希望在渲染器进程中从包含主进程代码(如 preload.ts)的文件中导入接口.
Why a separated fie ? Not sure if needed, but I prefer not having to import an interface from a file that contain main process code (like preload.ts) in renderer process.
// 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-743803249index.d.ts
typing and small example usage of contextBridge
: https://github.com/electron/electron/issues/9920#issuecomment-743803249另见:
这篇关于未在打包的应用程序中加载预加载脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!