首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Preload.js需要问题

Preload.js需要问题
EN

Stack Overflow用户
提问于 2022-03-15 10:07:05
回答 1查看 871关注 0票数 0

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

我的预装2.js:

代码语言:javascript
复制
const { BrowserWindow } = require("electron");
console.log(BrowserWindow);

在我窗口的控制台里它会返回

代码语言:javascript
复制
Undefined

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

我的main.js:

代码语言:javascript
复制
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()
    }
})

请帮帮我我快疯了

EN

回答 1

Stack Overflow用户

发布于 2022-03-16 10:56:31

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

为了加深你的知识,好好阅读一下电子的过程模型上下文隔离进程间通信页面。

一旦您阅读了这些页面(但不一定理解它们),让我们开始将它们拼接在一起,这样它们就可以作为一个整体工作了。

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

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

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

preload.js (主线程)

代码语言:javascript
复制
// 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 (主线程)

代码语言:javascript
复制
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 (渲染线程)

代码语言:javascript
复制
<!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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71480343

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档