我将
jsdom
与 jquery
一起使用来抓取 Node.js 应用程序中的静态 Web 内容。
jsdom
将 HTML 字符串转换为 DOM 树,包括 window
属性。我发现我必须将DOM的window
属性分配给global.window
,否则JQuery错误(说需要全局窗口对象)。为什么需要这个?
// Create DOM from HTML
const JSDOM = require('jsdom').JSDOM;
const jsDom = new JSDOM('<html>...</html>')
// Set up JQuery
const { window } = jsDom;
const { document } = window;
global.window = window;
const $ = global.jQuery = require('jquery');
// Scrape content
const tbl = $(document)
.find('#table-id')
.find('tr').each(function() {
// Do something with $(this).html()
})
还有,我经常看到这样的:
const $ = global.jQuery = require('jquery');
为什么需要global.jQuery
?
jQuery 期望在浏览器中运行。在浏览器中,
window
存在于全局空间中,jQuery 利用它来实现其某些功能。在 Node.js 中,您的代码在为包含该代码的文件创建的范围内运行。即使您不认为它是一个 module,Node.js 也不会区分文件顶层的所有 const
(和 let
)声明,声明作用域为您的变量。文件。所以 const { window } = jsDom;
没有将 window
放在全局空间中,并且 jQuery 无法访问它。
在 Node 中运行 jQuery 时,你有两种选择:
做你正在做的事情:首先将
window
暴露到全局空间中,然后加载jQuery。这很好用。您可以这样做:
const JSDOM = require('jsdom').JSDOM;
const jsDom = new JSDOM('<html>...</html>');
const { window } = jsDom;
const { document } = window;
const $ = global.jQuery = require("jquery")(window);
您也在询问
const $ = global.jQuery = require('jquery');
。根据我的经验,大多数依赖 jQuery 的库(例如 jQuery 插件)将其称为 jQuery
。他们在 IIFE 中运行是这样的:
(function ($) { // Inside the IIFE, jQuery is bound to $.
}(jQuery)); // jQuery is grabbed from the global space as jQuery.
因此您希望在全球范围内支持依赖它的库。
jQuery
const jsDom = new JSDOM('<html>...</html>');
const $ = global.jQuery = (require('jquery'))(jsDom.window);
的人来说,最简单的解决方案可能是在设置
import $ from 'jquery'
和 global.window
后动态导入测试中的模块:global.document
// MyFooUsejq.js
import $ from 'jquery';
export default class MyFooUsejq {
#$myDiv;
constructor(selector) {
this.#$myDiv = $(selector);
}
get innerHtml() {
return this.#$myDiv.html();
}
}