在 jsdom 加载的脚本中设置全局变量
Setting global variables in a script loaded by jsdom
我正在尝试在 Node 中运行一些浏览器代码.js以简化测试(deasync 是原因(。
目前,我使用 jsdom 来解析唯一的 html 文件。起初,我试图让它也加载脚本,这些脚本在<script>
标签中链接。但是由于相对文件路径的一些愚蠢问题,我已经切换到将脚本文件的绝对路径列表作为参数传递给jsdom.env
函数。
现在我很确定 jsdom 可以正确找到我的脚本,但我无法在其中设置任何全局变量。此外,console.log
在那里不起作用。我已经检查过,如果我通过require
命令加载脚本,那么全局变量和控制台输出都按预期工作。但是有了jsdom.env
它们就不起作用了。
我在Windows 7上使用Node.js版本4.2.6。以下 4 个文件用于重现问题(它们位于同一目录中(:
main.js - 从节点.exe开始:
var jsdom = require("jsdom");
require("./module");
var window = jsdom.env(
'<p><a class="the-link" href="https://github.com/tmpvar/jsdom">jsdom!</a></p>',
[
// "http://code.jquery.com/jquery.js",
"file://" + __dirname + "/myjquery.js",
"file://" + __dirname + "/script.js"
],
undefined,
function(error, window) {
console.log("contents of a.the-link:", window.$("a.the-link").text());
console.log(global.hello, window.hello, global.hi);
}
);
模块.js:
console.log("Hi!");
global.hi = 15
脚本.js:
console.log("Hello!");
global.hello = 126;
myjquery.js只是从 http://code.jquery.com/jquery.js 下载的jQuery。
它打印出:
Hi!
contents of a.the-link: jsdom!
undefined undefined 15
所以它肯定会正确加载myjquery.js
,因为它用于打印第一行。此外,它设置一个全局变量并在模块中打印一行,但不在脚本中执行此操作。
您能否解释一下原因并提出解决方法?
全局hello
global
是NodeJS的东西,而不是浏览器的东西。在你的script.js
中,如果你想在页面中设置全局变量(就像jQuery一样(,你要么在全局范围内声明它们:
var hello = 126;
或将它们分配为window
上的属性:
window.hello = 126;
或(在全局范围内,如果您不使用严格模式(以this
:
this.hello = 126;
如果您在 script.js
中执行任何操作,window.hello
将在您的回调中设置。
看到console.log
JSDom 页面非常清楚地表明,要查看console
窗口中的输出,您必须执行某些操作:
// Create and configure a virtual console
var virtualConsole = jsdom.createVirtualConsole();
virtualConsole.on("log", function (message) {
console.log("console.log called ->", message);
});
// Use it in the config object
var window = jsdom.env(
'<p><a class="the-link" href="https://github.com/tmpvar/jsdom">jsdom!</a></p>',
[
// "http://code.jquery.com/jquery.js",
"file://" + __dirname + "/myjquery.js",
"file://" + __dirname + "/script.js"
],
{ virtualConsole: virtualConsole }, // <== Here
function(error, window) {
console.log("contents of a.the-link:", window.$("a.the-link").text());
console.log(window.hello, global.hi);
}
);
看到错误
您提到您没有看到错误(这本来很有用,因为global.hello = 126;
确实会导致错误(;
JSDom 文档也讨论了如何侦听错误:
virtualConsole.on("jsdomError", function (error) {
console.error(error.stack, error.detail);
});
这只是在我们上面的console
设置之后进行的。现在,script.js
中的错误等将报告给 Node 控制台。
相对路径
你提到了相对路径的一些问题。仅供参考,这对我来说很好:
var window = jsdom.env(
'<p><a class="the-link" href="https://github.com/tmpvar/jsdom">jsdom!</a></p>',
[
"myjquery.js",
"script.js"
],
{ virtualConsole: virtualConsole },
function(error, window) {
console.log("contents of a.the-link:", window.$("a.the-link").text());
console.log(window.hello, global.hi);
}
);
。直接使用"http://code.jquery.com/jquery.js"
也是如此。
旁注:围绕virtualConsole
的 JSDom 文档显示的配置对象与我上面所做的略有不同。我这样做了:
var window = jsdom.env(
// ...
{ virtualConsole: virtualConsole },
// ...
);
而他们的文档显示了这一点:
var window = jsdom.env(
// ...
{ virtualConsole },
// ...
);
差异的原因是您仅在代码中使用 ES5,所以我进行了翻译。他们使用的是 ES2015 (ES6( 功能,如果属性名称和要从中获取属性的变量名称相同,则允许您使用速记指定属性。所以{ virtualConsole }
和{ virtualConsole: virtualConsole }
在 ES2015 中是完全相同的,但前者在 ES5 及更早版本中不起作用。如果您使用的是当前节点和 JSDom,则可以使用该 ES2015 功能。
- 在javascript函数中设置全局变量
- 如何从onclick函数设置全局变量并将其传递给另一个JS文件
- 使用eval()设置全局变量
- Ajax设置全局变量,但外部值消失
- 更新后,父视图未在 Electron 中的
上设置全局变量 - 为什么在定义回调/侦听器函数(异步消息传递,port.on)后没有立即设置全局变量
- 如何在不设置全局变量的情况下确定是否已调用函数
- 在函数内设置全局变量
- jQuery / JS设置全局变量,但卡在传递给AJAX自定义函数
- 在 jsdom 加载的脚本中设置全局变量
- 设置全局变量,但未获得预期结果
- 延迟调用 dojo widget 中的函数,直到设置全局变量
- 如何在Javascript中设置全局变量
- ngresource在成功响应中设置全局变量
- 如何在点击事件中设置全局变量
- 通过future函数循环和设置全局变量
- 尝试用javascript函数设置全局变量
- jQuery Ajax Post -无法使用回调函数设置全局变量
- jQuery load()函数不设置全局变量
- 设置全局变量并在jquery/javascript中访问它