为什么在没有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,因为如果与你的问题不一样的话,它似乎非常相似。