为什么require('child-process')在没有Internet连接的Node Webkit中不起作用?

gfr*_*ng4 6 node.js node-webkit nw.js

在最新的稳定版本(v0.18.8)上运行的Node-Webkit应用程序中,我有以下三行:

console.log("Check 1");
var spawn = require('child_process').spawn;
console.log("Check 2");
Run Code Online (Sandbox Code Playgroud)

当我有互联网时,我得到了预期的输出:

Check 1
Check 2
Run Code Online (Sandbox Code Playgroud)

当我断开互联网连接,或者没有网络可用时,我得到:

Check 1
net.js:10 Uncaught Error: EFILE
    at net.js:10:23
    at NativeModule.compile (bootstrap_node.js:531:7)
    at NativeModule.require (bootstrap_node.js:472:18)
    at internal/child_process.js:6:13
    at NativeModule.compile (bootstrap_node.js:531:7)
    at NativeModule.require (bootstrap_node.js:472:18)
    at child_process.js:12:23
    at NativeModule.compile (bootstrap_node.js:531:7)
    at Function.NativeModule.require (bootstrap_node.js:472:18)
    at Function.Module._load (module.js:446:25)
Run Code Online (Sandbox Code Playgroud)

console.log("Check 2")永远不会运行,并且脚本的其余部分被忽略.

我不需要互联网连接来要求一些东西,所以我很困惑这里出了什么问题.其他一些require()陈述也会发生此错误,但不是全部.例如,require('nw.gui')工作正常.

如何在require()没有互联网连接的情况下使用?

我正在运行Windows 10,64位.


以下是演示此问题的示例:

的index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Title</title>
</head>

<body>
    <p>Body</p>
</body>

<script type="text/javascript">
    console.log("Check 1");
    var spawn = require('child_process').spawn;
    console.log("Check 2");
</script>

</html>
Run Code Online (Sandbox Code Playgroud)

的package.json

{
    "name": "Demo",
    "version": "1.0.0",
    "main": "index.html"
}
Run Code Online (Sandbox Code Playgroud)

将这两个文件放在一个文件夹中,并使用带有Internet的Node-Webkit运行.按F12打开开发人员工具.使用Internet运行时应该没有错误,没有运行时会出错.

Aur*_*001 4

您似乎是c-ares 库(及其 Node 包装器)中错误的受害者,当 DNS 配置无效时(例如,如果您未连接到网络),该错误会影响某些 Windows 10 系统。

为什么会产生这样的影响child_process呢?

child_process模块requireinternal/child_process,它是标准库对 Node 提供的 C++ API 的包装器。相当奇怪的是,internal/child_process 需要net网络模块,然后加载cares_wrap节点用于 DNS 解析的 c-ares 包装器。

由于某种原因,internal/child_process 有一些 的帮助程序代码net,因此net必须加载该模块并且必须加载其所有依赖项(包括cares_wrap),这意味着如果您的 DNS 配置损坏,child_process则无法加载其依赖项internal/child_process

既然你得到了EFILE,这表明c-ares 的这一部分失败了

if (get_DNS_Windows(&line))
{
    status = config_nameserver(&servers, &nservers, line);
    ares_free(line);
} 

if (status == ARES_SUCCESS)
  status = ARES_EOF;
else
  /* Catch the case when all the above checks fail (which happens when there
     is no network card or the cable is unplugged) */
  status = ARES_EFILE;
Run Code Online (Sandbox Code Playgroud)

如果没有 C 调试器,就很难查明确切的问题,但我的猜测是get_DNS_Windows()在某种程度上失败了。

如何解决这个问题?

这是我的答案中最令人不满意的部分。使用 NW.js 的 LTS 时,您似乎会遇到此问题,因为如果 c-ares 初始化失败,旧版本的 Node 就会崩溃。在此提交中对此进行了更改,因此现在会捕获错误并将其作为 JS 异常抛出。因此,我相信 Node v6.7.0之后的行为将会发生变化。

据我所知,最好的解决方案是在虚拟机(或者可能是 Docker/Vagrant 容器)中运行 Node 来解决该问题,直到上游得到修复。向 Node 或 c-ares 报告该问题并提供尽可能多的信息绝对是值得的(这篇文章可能对某人有帮助,前提是我没有犯任何错误)。我也会观看#8966,因为它似乎与您的问题非常相似,即使不一样。