来自Electron渲染器进程的require()节点模块通过HTTP提供服务

时间:2016-09-07 12:54:46

标签: node.js require electron node-modules

通常,在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错误而失败。

3 个答案:

答案 0 :(得分:3)

终于弄明白了。在主进程中,找出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');

使用电子1.6.7完美地为我工作。

答案 1 :(得分:1)

您可以添加一个preload脚本,该脚本将属性添加到global / window变量。我命名为appRootappRoot仅具有preload-script的__dirname值。然后,您必须从preload-script的文件夹转到模块。我只是使用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>

答案 2 :(得分:-1)

遇到了类似的问题。尝试在 index.html 中通过HTTP提供 renderer.js ,就像这样,

canvas1

然后,根据docs,在 renderer.js 文件中的require之后使用添加遥控器加载模块。

<script src="/renderer.js"></script> </body>