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

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

console.log("Check 1"); var spawn = require('child_process').spawn; console.log("Check 2"); 

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

 Check 1 Check 2 

当我从互联网上断开连接,或者没有networking时,我得到:

 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) 

console.log("Check 2")从不运行,脚本的其余部分将被忽略。

我不应该需要互联网连接来需要的东西,所以我很困惑,这里有什么问题。 一些其他的require()语句也会发生这个错误,但不是全部。 例如, require('nw.gui')工作正常。

我如何在没有Internet连接的情况下使用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> 

的package.json

 { "name": "Demo", "version": "1.0.0", "main": "index.html" } 

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

看起来你是c-ares库 (及其节点包装器)中的一个bug的牺牲品,当DNSconfiguration无效(例如,如果你没有连接到networking),这会影响到一些Windows 10系统。

为什么这会影响child_process

child_process模块需要internal/child_process ,这是Node提供的C ++ API的标准库包装。 更奇怪的是, internal/child_process 需要net ,networking模块,然后加载cares_wrap ,围绕c-ares节点用于DNSparsing的包装。

出于某种原因, internal/child_process 有一些net辅助代码 ,所以net模块必须被加载,并且所有依赖项(包括cares_wrap )都必须被加载,这意味着如果你的DNSconfiguration被破坏, 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; 

如果没有Cdebugging器,就很难确定确切的问题,但我的猜测是get_DNS_Windows()以某种方式失败。

这个问题怎么解决?

这是我的答案更令人不满意的部分。 当使用NW.js的LTS时,看起来像是遇到了这个问题 ,因为如果c-ares初始化失败,旧版本的Node就会崩溃。 在这个提交中这被改变了,所以错误现在被捕获并且被引发为JSexception。 因此,我相信Node v6.7.0之后的行为将会发生改变。

据我所知,最好的解决scheme是在一个虚拟机(或者一个Docker / Vagrant容器)中运行Node来解决这个问题,直到它被固定在上游。 这肯定是值得向Node或者c-ares报告这个问题的尽可能多的信息(如果我没有犯任何错误,这个post可能对某人有帮助)。 我也会看#8966,因为如果与你的问题不一样的话,它似乎非常相似。