预加载.js需要问题



最近我开始用Electron框架练习javascript,但我遇到了预加载.js功能的问题。也许我不知道如何使用它,但我不能要求一些电子常数,因为它返回未定义的

我的preload2.js:

const { BrowserWindow } = require("electron");
console.log(BrowserWindow);

在我的窗口控制台中,它返回

Undefined

我排除了问题可能是我的预加载没有正确执行,但可能是:

我的main.js:

const { app, BrowserWindow } = require('electron');
function createWindow() {
console.log(app.getAppPath());
const win = new BrowserWindow({
width: 1000,
height: 600,
//Web preferences può utilizzare il preload.js 
webPreferences: {
preload: app.getAppPath() + "\preload2.js",
}
});
win.loadFile('index.html');
}

app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})

请帮帮我,我疯了

如果没有一个结构良好的基本示例,就很难正确使用Electron的preload.js脚本。互联网上的许多例子将预加载脚本的主要功能(即管理主线程和渲染线程之间的通信通道(与这些通道的实现相结合。

为了进一步了解您的知识,请仔细阅读Electron的过程模型、上下文隔离和过程间通信页面。

一旦你阅读了这些页面(但不一定理解它们(,让我们开始将它们拼接在一起,使它们成为一个整体。


如前所述,preload.js脚本的目的是在主线程和渲染线程之间进行通信。如果向预加载脚本添加大量函数,那么预加载脚本很快就会变得不堪重负。

作为一种替代方法,我只使用我的(唯一的(preload.js脚本来管理IPC(按通道名称(。这意味着我指定了在主线程和渲染线程之间传输或接收的白名单通道名称。使用的任何不在白名单上的频道名称都将被拒绝通过。您还可以在传输频道名称时发送数据,以便在另一端接收数据。

好的,让我们看看preload.js文件。

preload.js(主线程(

// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
// White-listed channels.
const ipc = {
'render': {
// From render to main.
'send': [
'message:fromRender'
],
// From main to render.
'receive': [
'message:toRender'
],
// From render to main and back again.
'sendReceive': []
}
};
// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
// Allowed 'ipcRenderer' methods.
'ipcRender', {
// From render to main.
send: (channel, args) => {
let validChannels = ipc.render.send;
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, args);
}
},
// From main to render.
receive: (channel, listener) => {
let validChannels = ipc.render.receive;
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`.
ipcRenderer.on(channel, (event, ...args) => listener(...args));
}
},
// From render to main and back again.
invoke: (channel, args) => {
let validChannels = ipc.render.sendReceive;
if (validChannels.includes(channel)) {
return ipcRenderer.invoke(channel, args);
}
}
}
);

在上面的代码中,您将看到频道名称message:fromRendermessage:toRender已添加到白名单中。

注意:像BrowserWindow这样的对象不能通过IPC发送,因为它们不可串行。有关详细信息,请参阅对象序列化。


现在,在您的main.js文件中,除了预加载脚本的路径之外,一切看起来都很好。让我们改变一下。

main.js(主线程(

const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronIpcMain = require('electron').ipcMain;
const nodePath = require("path");
let win;
function createWindow() {
const win = new electronBrowserWindow({
x: 0,
y: 0,
width: 1000,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js')
}
});
win.loadFile('index.html')
.then(() => { win.show(); })
// Send message to (win) render thread
.then(() => { win.webContents.send('message:toRender', 'Hello from the main thread.' )};
return win;
}
electronApp.on('ready', () => {
win = createWindow();
});
electronApp.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// Listen for message from (any) render thread.
electronIpcMain.on('message:fromRender', (event, message) => {
console.log(message);
})

您会注意到我添加了两个新的代码部分。一个用于向渲染线程发送消息,另一个用于从渲染线程接收特定消息。


最后,让我们为我们的基本index.html文件添加功能。

index.html(渲染线程(

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>

<body>
<label for ="button">Send message to main thread: </label>
<input type="button" id="button" value="Send">        
</body>

<script>
// Listen for message from the main thread
window.ipcRender.receive('message:toRender', (message) => {
console.log(message);
});

document.getElementById('button').addEventListener('click', () => {
// Send a message to the main thread
window.ipcRender.send('message:fromRender', 'Hello from the render thread.');
});
</script>
</html>

启动应用程序后,渲染线程控制台应显示Hello from the main thread

单击Send按钮后,主线程应显示Hello from the render thread

如果你需要任何澄清或进一步解释,请告诉我。

最新更新