Electron 结合了 Chromium、Node.js 和用于调用操作系统本地功能的 API(如打开文件窗口、通知、图标等,基于 Electron 的开发,就好像开发一个网页一样,而且能够无缝地使用 Node。或者说:就好像构建一个 Node app,并通过 HTML 和 CSS 构建界面。
那么如何在页面中调用 Node API 呢?
碰到了一些坑…
先从页面加载方式说起,Electron 中加载页面的方式有两种:
一种是直接加载本地文件,另一种是通过 http 网络请求页面。
//方法1 本地路径 win.loadURL(url.format({ pathname: path.join(__dirname, '/dist/index.html'), protocol: 'file:', slashes: true }));
//方法2 网络路径 win.loadURL('http://localhost:3000');
现在我想要在某个js文件中引用一个本地的 npm 包,其中包含 Node API,所以在浏览器中无法使用。
var local = window.nodeRequire('local');
此时出现一个问题,使用方法1运行正常,但使用方法2时报错,但是如果使用方法1,每次修改完代码都需要先打包一遍,再使用 Electron 启动,耗时耗力啊。继续寻找解决方法。
can not find module xxx
调试发现在使用网络文件时,在调用 module.js 中的 Module._load 函数时参入的参数 parent 为
重点在下面两个变量,从 Http 加载页面时,由于路径是网络地址,所以 Electron 将文件名设置为 Electron 安装目录下的 init.js.
filename: "C:\Users\asus\AppData\Roaming\npm\node_modules\electron\dist\resources\electron.asar\renderer\init.js"
paths: Array[0]
而在使用本地 index.html 时,pathname 指向正确的路径,而且 paths 中也包含了多个 node_modules 路径,module在初始化时会将当前路径以及上一级、上上一级…直到根目录的 node_modules 作为搜索路径。
filename: "E:\WebStormWorkspace\electron_require\index.html"
从下面 module.js 源码可以看到,文件名解析的时候正式利用了这个 paths 中的路径。因为 paths 中的空的,所以找不到所需要的模块。
其实 Electron 是从安全的角度考虑,在从 Http 请求中加载网页时,如果能直接调用本地的一些模块,会比较危险。
Module._resolveFilename = function(request, parent, isMain) { if (NativeModule.nonInternalExists(request)) { return request; } var resolvedModule = Module._resolveLookupPaths(request, parent); var id = resolvedModule[0]; var paths = resolvedModule[1]; // look up the filename first, since that's the cache key. debug('looking for %j in %j', id, paths); var filename = Module._findPath(request, paths, isMain); if (!filename) { var err = new Error("Cannot find module '" + request + "'"); err.code = 'MODULE_NOT_FOUND'; throw err; } return filename; };
此时很自然地想到可以把所需要模块的路径加入到 paths 中去,但这其实是不可行的,Electron 包含主进程和渲染进程,主进程就是这里命名main.js 的文件,该文件是每个 Electron 应用的入口。它控制了应用的生命周期(从打开到关闭)。它能调用原生元素和创建新的(多个)渲染进程,而且整个 Node API 是内置其中的。
渲染进程就是一个浏览器窗口,现在我们的 js 跑在渲染进程里面,所以我们并不能直接在主进程里面修改渲染进程的数据。
Electron 提供了 IPC 接口专门用于主进程和渲染进程之间的通信,他提供了同步和异步两种方法,同步方法直接设置 event.returnValue,异步方法使用 event.sender.send(…).
// In main process. const {ipcMain} = require('electron') ipcMain.on('asynchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.sender.send('asynchronous-reply', 'pong') }) ipcMain.on('synchronous-message', (event, arg) => { console.log(arg) // prints "ping" event.returnValue = 'pong' })
// In renderer process (web page). const {ipcRenderer} = require('electron') console.log(ipcRenderer.sendSync('synchronous-message', 'ping')) // prints "pong" ipcRenderer.on('asynchronous-reply', (event, arg) => { console.log(arg) // prints "pong" }) ipcRenderer.send('asynchronous-message', 'ping')
但其实有更简单的方法,使用 remote 模块来直接调用:
const remote = window.nodeRequire('electron').remote; var local = remote.require('local');
这样子就可以直接使用外部模块了,这里为什么能引用 electron 模块,而其他的不可以呢?
继续看源码, Electron 重写了 Module._resolveFilename 函数,在 require(‘electron') 时,就直接返回路径,所以就可以找到啦。
// Patch Module._resolveFilename to always require the Electron API when // require('electron') is done. const electronPath = path.join(__dirname, '..', process.type, 'api', 'exports', 'electron.js') const originalResolveFilename = Module._resolveFilename Module._resolveFilename = function (request, parent, isMain) { if (request === 'electron') { return electronPath } else { return originalResolveFilename(request, parent, isMain) } } }.call(this, exports, require, module, __filename, __dirname); });
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 邱锋泽.2024-COlOR.Free【发现梦想】【FLAC分轨】
- 群星 《10年朋友Vol.8》滚石台湾版[WAV+CUE][1.G]
- 群星《2024好听新歌31》十倍音质 U盘音乐 [WAV分轨][1.1G]
- 群星《全天后》华纳[WAV+CUE][1.1G]
- 许乐《声愿HQCD》[正版原抓WAV+CUE]
- 黄凯芹《给你留念》头版限量编号MQA-UHQCD2024[低速原抓WAV+CUE]
- 黑鸭子2008-今生最爱[首版][WAV+CUE]
- 彭海桐.2000-好好想想你【SONY】【WAV+CUE】
- 群星.1995-亚洲电视剧集主题曲大全·乐作剧2CD【滚石】【WAV+CUE】
- 林强.1992-春风少年兄【魔岩】【WAV+CUE】
- 世界顶级汽车音响试音王《金色的草原》24K金碟[低速原抓WAV+CUE][1G]
- 周深 /Faouzia《解密 电影原声带》[320K/MP3][39.32MB]
- 周深 /Faouzia《解密 电影原声带》[FLAC/分轨][199.46MB]
- 英雄联盟s14亚军队伍是哪支 英雄联盟s14亚军队伍介绍
- 英雄联盟s14夺冠队伍是哪支 英雄联盟s14夺冠队SKT T1队伍介绍