通常,在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
错误而失败。
答案 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变量。我命名为appRoot
。 appRoot
仅具有preload-script的__dirname
值。然后,您必须从preload-script的文件夹转到模块。我只是使用path.join()
使其干净。
这类似于@logidelic的方法,但不必弄乱IPC消息。
mainWindow = new BrowserWindow({
webPreferences: {
preload: 'preload.js'
}
})
global.appRoot = window.appRoot = __dirname
<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>