electron初探问题总结
2019-06-10 14:41
671 查看
使用electron时间不是很久,随着使用的深入慢慢的也遇到一些问题,下面总结一下遇到的问题与大家分享,避免趟坑。
1、webview与渲染进程renderer间通信
与渲染进程之间的通信不同,渲染进程与webview之间的通信,在webview层通过调用
sendToHost方法来向渲染进程通信;而在渲染进程测通过webview提供的
ipc-message事件来向webview通信。具体如下面代码所示:
// renderer环境,获取webview,然后注册事件 webview.addEventListener('ipc-message', (event) => { // 通过event.channel的值来判断webview发送的事件名 if (event.channel === 'webview_event_name') { console.log(event.args[0]) // 123 } }) webview.send('renderer_event_name', '456') // webview环境 const {ipcRenderer} = require('electron') ipcRenderer.on('renderer_event_name', (e, message) => { console.log(message); // 456 ipcRenderer.sendToHost('webview_event_name', '123') })
2、BrowserWindow加载第三方网站,集成node模块时导致第三方模块不可用
具体来说,就是在使用
new BrowserWindow时,配置其webPreferences选项的
nodeIntegration值为true,即:
new BrowserWindow({ webPreferences: { nodeIntegration: true // 注入node模块 } })
这样,第三方网站按照CMD格式加载前端模块时如下所示,
!function(a, b) { "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function(a) { if (!a.document) throw new Error("jQuery requires a window with a document"); return b(a) } : b(a) }(this, fn);
可以看出,若electron窗口配置集成node模块的话,前端模块占用了node关键字
module,导致前端页面的模块成了node的模块,以jQuery为例,依赖jQuery的模块会出现如下错误信息:
Uncaught ReferenceError: $ is not defined
知道问题所在,解决问题有两种思路:
不启用node功能,即设置
nodeIntegration: false
。这种方式比较粗暴,不能更好的拓展electron应用在页面加载模块依赖之前改变
module
,之后恢复module指向node模块。
针对第二种方法,github上有人提出解决方案。我们在不可控的加载第三方网站时,利用BrowserWindow的前置注入脚本
preload来提供修改module指向,可参考代码如下:
// renderer var win = new BrowserWindow({ ... webPreferences: { nodeIntegration: true, preload: process.cwd() + '/app/resource/preload.js' } }); // preload.js // electron的BrowserWindow设置nodeIntegration为true时,导致页面可以访问node的module影响页面正常模块引入功能,如jQuery document.addEventListener('DOMNodeInserted', function(event){ // 页面内容加载之前需要引入的一些代码 if (document.head && !document.getElementById('module')) { var script = document.createElement('script'); script.setAttribute('id', 'module'); script.innerHTML = "if (typeof module === 'object') {window.module = module; module = undefined;}" document.head.appendChild(script); } }); document.addEventListener('DOMContentLoaded', function(event) { // 页面内容加载之后需要引入的一些操作 var script = document.createElement('script'); script.innerHTML = `if (window.module) module = window.module;` document.body.appendChild(script); })
3、预加载脚本preload的问题
BrowserWindow提供的
preload的配置是为了在页面第一次加载文档之前预先加载js脚本文件,其需要注意3个问题:
- preload配置值不能直接为脚本字符串,否则不会执行
- preload配置的脚本文件路径,只能为本地文件,其协议必须是file:、asar:二者之一
- preload脚本仍然有能力去访问所有的 Node APIs, 即使配置nodeIntegration: false。但是当这个脚本执行执行完成之后,通过Node 注入的全局对象(global objects)将会被删除。
preload是在脚本加载之前执行,其有三个阶段如下,具体可以参考#217 Electron 深度实践总结:
// --------------------------------------------------- // 第一阶段:在页面加载之前需要执行的相关代码 // ... // ------------------------------------------------------- document.addEventListener('DOMNodeInserted', (event) => { // 第二阶段:页面内容加载之前需要引入的一些代码 // ... }) // ------------------------------------------------------- document.addEventListener('DOMContentLoaded', (event) => { // 第三阶段:页面内容加载之后需要引入的一些操作 // ... }) // -------------------------------------------------------
可以看出:
preload环境可以使用Node API,又能访问DOM、BOM的特殊环境,即使dom文档还未形成之前。
参考文献
相关文章推荐
- 01背包问题总结
- JVM调优总结(3):垃圾回收面临的问题
- Reviewboard 使用和安装问题总结
- 总结十个Angular.js由浅入深的面试问题
- iOS7 UI改变总结 & iOS7适配遇到的一些问题
- 第一个小程序---计算器开发中遇到的问题总结
- C语言整数类型及printf格式化输出问题总结复习及进制转换的简单实现
- PowerShell中运行CMD命令的技巧总结(解决名称冲突和特殊字符等问题)
- 关于中的“回车”在后台,mysql数据库,html和中的显示问题总结...
- 发布web服务问题总结
- ios7版本适配问题总结(二)
- 关于.NET邮件的收发问题总结(带附件)
- 关于乱码问题的小小总结
- 问题总结(一)使用代码调整SharePoint WebPart 视图和列表菜单
- J2EE开发 原始JDBC开发中的问题总结
- 【Java】关于文件路径问题总结
- java.lang.NoSuchMethodError: antlr.collections.AST.getLine()I问题解决及总结。
- 总结骏汇项目的js问题(三)之充值优惠
- Java基础:HashMap假死锁问题的测试、分析和总结
- centos6.4无人值守安装问题总结