来自 Electron 渲染器进程的 require() 节点模块,通过 HTTP 提供服务
Posted
技术标签:
【中文标题】来自 Electron 渲染器进程的 require() 节点模块,通过 HTTP 提供服务【英文标题】:require() node module from Electron renderer process served over HTTP 【发布时间】:2017-01-15 04:21:51 【问题描述】:通常,在 Electron 应用程序中,您可以在主进程和渲染器进程中 require
节点模块:
var myModule = require('my-module');
但是,如果页面是通过 HTTP 而不是从本地文件系统加载的,这似乎不起作用。换句话说,如果我打开一个这样的窗口:
win.loadURL(`file://$__dirname/index.html`);
我可以require
一个节点模块没有问题。但如果我改为打开这样的窗口:
win.loadURL(`http://localhost:1234/index.html`);
我不再可以在我的网页中使用require
节点模块 - 我在网页的控制台中获得了Uncaught Error: Cannot find module 'my-module'
。有没有办法在通过 HTTP 提供的 Electron 页面中使用节点模块?
一点背景:我的公司正在构建一个应用程序,该应用程序需要能够作为 Web 应用程序和在 Electron shell 中托管。为了使这两个环境更简单和一致,我的 Electron 应用程序启动了一个本地 Web 服务器并打开托管在 http://localhost:1234
的应用程序。现在我希望能够使用electron-spell-check-provider
在应用程序中添加拼写检查/拼写建议。这个模块需要在渲染器进程中导入和初始化,所以我试图在我的网页中require('electron-spell-check-provider')
,但这失败了Cannot find module
错误。
【问题讨论】:
我不确定,但似乎 http 版本正在为文件获取一些不同的实际路径。尝试通过以下方式更改 require 语句:=> "require('./electron-spell-check-provider')" 你试过了吗:require('electron').remote.require('electron-spell-check-provider')
?
您最终解决了这个问题吗? remote.require() 对我有用,但这并不总是一个好的解决方案。还有其他方法吗?
【参考方案1】:
您可以添加一个预加载脚本,该脚本将属性添加到全局/窗口变量。我将我的命名为appRoot
。 appRoot
仅具有预加载脚本的 __dirname
值。然后,您必须从预加载脚本的文件夹转到您的模块。我只是使用path.join()
让它变得干净。
这类似于@logidelic 的方法,但不必弄乱 IPC 消息。
main.js
mainWindow = new BrowserWindow(
webPreferences:
preload: 'preload.js'
)
preload.js:
global.appRoot = window.appRoot = __dirname
index.html:
<script>
const join = require('path')
require(join(appRoot, 'rendererApp'))
</script>
【讨论】:
这对我不起作用。这样做:``` const path = require('path') const electron = require('electron') const appPath = electron.remote.app.appPath const usb = require(path.join(appPath, 'node_modules', ' usb')) ```【参考方案2】:终于想通了。在主进程中,找出node_modules目录的绝对路径,如:
var nodeModDir = require.resolve('some-valid-module');
var dirnm = 'node_modules';
var pos = nodeModDir.lastIndexOf(dirnm);
if(pos != -1)
nodeModDir = nodeModDir.substr(0, pos+dirnm.length+1);
现在通过一些 IPC 获取渲染器进程的路径。最后,在渲染器中,您现在可以要求使用绝对路径:
var mymod = require(nodeModDir+'some-valid-module');
electron 1.6.7 非常适合我。
【讨论】:
【参考方案3】:遇到了类似的问题。尝试像这样在 index.html 中通过 HTTP 提供 renderer.js,
<script src="/renderer.js"></script>
</body>
然后,根据docs,在 renderer.js 文件中的 require 之后使用添加远程加载您的模块。
var spellCheck = require('electron-spell-check-provider').remote;
【讨论】:
渲染器包含什么?以上是关于来自 Electron 渲染器进程的 require() 节点模块,通过 HTTP 提供服务的主要内容,如果未能解决你的问题,请参考以下文章