I'm using jsdom
together with jquery
to scrape static web content in a Node.js application.
jsdom
converts an HTML string to a DOM tree, including a window
property. I found that I had to assign the DOM's window
property to global.window
, otherwise JQuery errors (saying that a global window object is required). Why is this required?
// 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()
})
Also, I have often seen this: const $ = global.jQuery = require('jquery');
Why is global.jQuery
required?
jQuery expects to be running in a browser. In a browser window
is present in the global space, and jQuery makes use of it for some of its features. In Node.js, your code is running in a scope created for the file that contains it. Even if you don't think of it as a module, Node.js does not make the distinction all of your const
(and let
) declarations at the top level of your file declare variables that are scoped to your file. So const { window } = jsDom;
is not putting window
in the global space, and it is not accessible to jQuery.
You have two choices when you run jQuery in Node:
Do what you are doing: first expose window
into the global space, then load jQuery. This works fine.
You can instead do this:
const JSDOM = require('jsdom').JSDOM;
const jsDom = new JSDOM('<html>...</html>');
const { window } = jsDom;
const { document } = window;
const $ = global.jQuery = require("jquery")(window);
You are asking also about const $ = global.jQuery = require('jquery');
. In my experience, most libraries that depend on jQuery (like jQuery plugins for instance) refer to it as jQuery
. They run in an IIFE like this:
(function ($) { // Inside the IIFE, jQuery is bound to $.
}(jQuery)); // jQuery is grabbed from the global space as jQuery.
So you want jQuery
in the global space to support libraries that depend on it.