Search code examples
javascriptnode.jsjsdom

JSDOM is not loading JavaScript included with <script> tag


Note: This question is not a duplicate of other existing questions because this question does not use jsdom.env() function call which older version of JSDOM use.

File bar.js:

console.log('bar says: hello')

File foo.js:

var jsdom = require('jsdom')
var html = '<!DOCTYPE html><head><script src="bar.js"></script></head><body><div>Foo</div></body>'
var window = new jsdom.JSDOM(html).window
window.onload = function () {
  console.log('window loaded')
}

When I run foo.js, I get this output.

$ node foo.js
window loaded

Why did bar says: hello output did not come? It looks like bar.js was not loaded. How can I make jsdom load the file in the script tag?

[EDIT/SOLUTION]: Problem solved after following a suggestion in the answer by Quentin. This code works:

var jsdom = require('jsdom')
var html = '<!DOCTYPE html><head><script src="bar.js"></script></head><body><div>Foo</div></body>'
var window = new jsdom.JSDOM(html, { runScripts: "dangerously", resources: "usable" }).window
window.onload = function () {
  console.log('window loaded')
}

Solution

  • Go to the JSDOM homepage.

    Skim the headings until you find one marked Executing scripts

    To enable executing scripts inside the page, you can use the runScripts: "dangerously" option:

    const dom = new JSDOM(`<body>
      <script>document.body.appendChild(document.createElement("hr"));</script>
    </body>`, { runScripts: "dangerously" });
    
    // The script will be executed and modify the DOM:
    dom.window.document.body.children.length === 2;
    

    Again we emphasize to only use this when feeding jsdom code you know is safe. If you use it on arbitrary user-supplied code, or code from the Internet, you are effectively running untrusted Node.js code, and your machine could be compromised.

    If you want to execute external scripts, included via <script src="">, you'll also need to ensure that they load them. To do this, add the option resources: "usable" as described below.