【问题标题】:electron: NodeJS 'net' module returns empty object电子:NodeJS 'net' 模块返回空对象
【发布时间】:2021-02-14 21:44:57
【问题描述】:

我刚开始开发我的第一个电子应用程序并导入了一些使用net 模块的现有代码。 当我从电子应用程序导入代码时,net 模块返回一个空对象。

const net = require('net'); // => {}

我认为电子将节点与所需的本机模块捆绑在一起,所以我对为什么导入不起作用有点困惑。

编辑:我已经使用vue-cli-tools 引导应用程序,因此它使用 webpack 来捆绑依赖项。不确定这是否重要。

【问题讨论】:

  • 您在应用程序的哪个部分使用它? Main 进程还是 Renderer 进程?
  • 说实话,我不确定哪个代码在哪个进程中运行。我正在从 Vue 组件中导入一个使用 net 模块的模块,所以我猜是渲染器进程?

标签: javascript node.js webpack electron


【解决方案1】:

我认为电子将节点与所需的本机模块捆绑在一起,

确实如此,但是将浏览器运行时和 node.js 运行时捆绑在一起仍然会给您留下两个不同的运行时。

了解Main and Renderer processes 之间的区别对于 Electron 开发至关重要。

主进程在 Node.js 运行时上运行,并且可以访问 Node.js API(如 net)。

渲染器进程在 Chromium 上运行,并且可以访问浏览器 API(如 DOM)。

您无法从客户端 Vue 代码访问 net,因为它正在 Renderer 进程中运行。

你需要在主进程中创建一个服务,并在它和渲染器中运行的东西之间交换数据。

这通常使用IPC apis 完成。

// In main process.
const { ipcMain } = require('electron')
ipcMain.on('message-from-browser', (event, arg) => {
  const something = doSomethingWithNetModule()
  event.reply('reply-to-browser', something)
})

// In renderer process (web page).
const { ipcRenderer } = require('electron')

ipcRenderer.on('asynchronous-reply', (event, arg) => {
    doSomethingWithDataFromNetModule(arg)
})

ipcRenderer.send('message-from-browser', 'do something with the net module please')

请注意,由于您使用的是 Webpack,您将遇到require("electron") 的问题,这些问题在in this question 中进行了解释。

【讨论】:

  • 啊,这是有道理的,我实际上预计会出现这样的情况。我只是想知道为什么它必须以这种方式工作,因为它无疑会使事情变得更加复杂。
  • 在 Chromium 和 Node 之间提供粘合剂比将一个的所有功能转移到另一个的工作要少得多......项目已发布。
  • @Quentin 这不太正确,因为渲染器进程 可以 也可以访问节点 API。通常情况下,最好只在主流程中执行此操作,但这取决于您的偏好和您在做什么。只要启用了nodeIntegration,您当然可以从渲染器进程中访问net(和fshttp 等)。
【解决方案2】:

Weback 可能正在尝试捆绑 net。尝试两件事:

vue.config.js 中使用 webpack 配置 externals 选项。 (请注意,您可能需要在下面的选项中使用 commonjs2,请参阅externals 文档了解更多信息)

module.exports = {
  configureWebpack: {
    externals: {
      net: 'commonjs net',
    }
  },
}

或者(不那么推荐,但在过去发现正确的 webpack 设置被证明是顽固的),重命名 require 以便 webpack 忽略它:

const _require = require;
//...
const net = _require('net');

【讨论】:

  • 谢谢,但如果我添加 externals 部分,它会输出另一个错误:require is not defined。谷歌说我必须指定,但我尝试了target: 'node'(导致exports is not defined)和target: 'web'(再次导致未定义的要求)。 编辑:我不想覆盖require。一定有别的办法吗?
  • 很高兴看到您现在得到了有效的答案;)。您可以从渲染器访问节点模块(我们在我们的应用程序中这样做),但实际上保持对主进程的访问通常是一种更好的模式。第二种方法在尝试找出您的问题的实际情况时通常很有帮助,因此您至少知道应该关注哪里以找到更好的解决方案。
  • 老实说,我仍在为此苦苦挣扎。我感到困惑的一件事是:我可以在渲染器进程(例如 Vue)中使用已安装的节点模块,对吧?这些模块本身可能需要本机节点模块,对吗?那么它是如何工作的呢?
  • Webpack 用于打包。 Vue 将被捆绑到渲染过程中,因此实际上渲染代码没有实际的 requireimport 语句。你遇到问题的地方是内部节点模块,如fs,正如你发现的net,因此也不是那些本身使用内部或绑定到其他低级接口的模块(我们使用keytar属于这一类)。使用 externals 基本上是告诉 webpack 将要求保留在适当的位置。为了让它在渲染器进程中工作,它需要启用节点环境。
猜你喜欢
  • 2019-02-23
  • 2020-05-12
  • 2017-02-28
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 2020-03-03
  • 2016-10-19
  • 1970-01-01
相关资源
最近更新 更多