Throw new error jquery requires a window with a document

So everything was working just fine and great until doing npm update and now things do not work quite as they used to. A little background: in my code I use jquery to parse textual html. I do not...

So everything was working just fine and great until doing npm update and now things do not work quite as they used to.

A little background: in my code I use jquery to parse textual html. I do not use a window and I don’t use jsdom. It used to work just fine to do this:

$ = require("jquery"); 
$(html).find("<h1>").html("The title"); 

But now I get this:
jQuery requires a window with a document

How do I fix this?

asked Jan 26, 2014 at 0:17

Martin's user avatar

1

This worked for me

var jsdom = require('jsdom');
$ = require('jquery')(new jsdom.JSDOM().window);

Justin Geeslin's user avatar

answered Jan 18, 2018 at 11:38

Aravinthan K's user avatar

Aravinthan KAravinthan K

1,7052 gold badges19 silver badges22 bronze badges

3

The npm package for jQuery definitely used to include jsdom with it, which is why it would work at all in Node: jQuery needs to have some kind of DOM environment to work with.

You can check that old versions used to have it by doing npm install jquery@1.8.3. You’ll see jsdom being installed with it. For some reason they seem to have removed jsdom from the recent releases. I don’t know why.

However, using jsdom 7.x to run jQuery code is simple:

var jsdom = require("jsdom");
var window = jsdom.jsdom().defaultView;

jsdom.jQueryify(window, "http://code.jquery.com/jquery.js", function () {
  var $ = window.$;
  $("body").prepend("<h1>The title</h1>");
  console.log($("h1").html());
});

The path could be changed to a different version of jQuery or to a local file.

Note: Earlier versions of jsdom, including the 3.x series, would need the line var window = jsdom.jsdom().parentWindow; instead of var window = jsdom.jsdom().defaultView;. 4.x made it so that parentWindow no longer works.

answered Jan 26, 2014 at 1:09

Louis's user avatar

LouisLouis

144k28 gold badges270 silver badges314 bronze badges

0

I solved it. had to first remove jsdom and jquery then npm install jsdom jquery.

Then this:

var jsdom = require("jsdom"); 
$ = require("jquery")(jsdom.jsdom().createWindow()); 

Turns out that it was important that I had the latest version. Otherwise it didn’t work..

answered Jan 26, 2014 at 2:37

Martin's user avatar

MartinMartin

3,4453 gold badges26 silver badges30 bronze badges

2

jsdom seems to have a new version therefore now it works on a slightly different way. Here you have an example:

const { JSDOM } = require("jsdom");
const myJSDom = new JSDOM (html);
const $ = require('jquery')(myJSDom.window);

Now you can search as you used to do on jQuery:

$("<h1>").html("The title");

Mind the jQuery installation as you should write jquery all lowercase, like npm install jquery.

answered May 8, 2018 at 10:21

Hola Soy Edu Feliz Navidad's user avatar

0

You can try the following with these version settings in your package.json:

"jquery": "^2.1.1",
"jsdom": "^1.0.0-pre.3"

Say you have a file called page.htm:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>Html page</h1>
    <div class="left">
        <p>left content</p>
    </div>
</body>
</html>

Then, you can read from file, create a DOM and window from it with JSDOM and pass it to jquery:

var jsdom = require("jsdom").jsdom;
var fs = require('fs');
fs.readFile('page.htm', {encoding: "utf8"}, function (err, markup) {
  if (err) throw err;
  var doc = jsdom(markup);
  var window = doc.parentWindow;
  var $ = require('jquery')(window)
  var outerLeft = $(".left").clone().wrap('<div></div>').parent().html();
  var innerLeft = $(".left").html();
  console.log(outerLeft, "and ...", innerLeft);
});

will output:

<div class="left">
<p>left content</p>
</div> and ... 
<p>left content</p>

answered Aug 26, 2014 at 23:39

AJ Meyghani's user avatar

AJ MeyghaniAJ Meyghani

4,2891 gold badge30 silver badges35 bronze badges

0

(2018) — New jsdom API

var jsdom = require('jsdom'),
    { JSDOM } = jsdom,
    jsdom_options = {
      runScripts: "dangerously",
      resources: "usable"
    };

// external script example:
var DOM = new JSDOM(`<!DOCTYPE html><html><head><script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script></head><body></body></html>`, jsdom_options);

// local script example:
var jQuery = fs.readFileSync("../../jQuery.js", { encoding: "utf-8" });
var DOM = new JSDOM(``, { runScripts: "dangerously" });

var scriptElm = window.document.createElement("script");
scriptElm.textContent = jQuery;
DOM.window.document.head.appendChild(scriptElm);

References:

  1. Loading external scripts
  2. Loading local scripts

answered Nov 12, 2015 at 14:46

vsync's user avatar

vsyncvsync

113k55 gold badges297 silver badges382 bronze badges

0

I plopped this on the top of my Node.js (server) file that uses jQuery to help render html text …

var jsdom = require("jsdom").jsdom;
jsdom.env({
    html : "<html><body></body></html>",
    done : function(errs, window) {
        global.window = window;
    }
});

and everything comes up roses.

answered Sep 12, 2014 at 0:06

Mark Peterson's user avatar

2021 answer

Faced the same issue recently

This works with "jquery": "^3.5.1" and "jsdom": "^16.4.0"

const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const jquery = require('jquery')

getHtmlFromSomewhere(function (err, data) {
    handleError(err)
    
    console.log("html is ", data)
    const dom = new JSDOM(data);

    const $ = jquery(dom.window);
    const someData = $("#dataTable tbody tr:last td:eq(1)")

    console.log("some data is: ", someData.text())
});

The gist of the solution is parsing your HTML using JSDOM in order to obtain a window object. Then wrap said window object using jquery

And that’s it, you can use jquery selector functions in the parsed document

answered Jan 29, 2021 at 13:22

Martín Zaragoza's user avatar

You have to provide a window object. To do this, just pass parentWindow from jsdom:

var jsdom = require("jsdom"); 
var $ = require("jquery")(jsdom.jsdom().parentWindow);

answered Dec 16, 2014 at 16:53

neoRiley's user avatar

neoRileyneoRiley

4556 silver badges11 bronze badges

0

I know that I am not in the correct year here, but I may have found a better way, then the ways that offered here. If you call the scripts from the .html file, the script will know the document, and it solved the problem for me (at least for now). example:

index.html:

<html>
<head>
<meta charset="UTF-8">
<!--Scripts-->
<script>
    window.$ = window.jQuery = require('../js/libs/jQuery.js');
</script>
<script src="../js/libs/materialize.js"></script>
<script>
    const init = require("../js/initialize/initialize.js");
    init.initializer.main_init();
</script>

<!--Styles-->
<!--Libraries-->
<link rel="stylesheet" href="../scss/libs/materialize.css" />
</head>
</html>

initialize.js:

var jQuery = require('jquery');

(function($, global, undefined) {
    "use strict";

    var Initialize = function() {
        var initializer;          
        initializer = {
            materialize_init: function () {
            console.log(document.getElementsByClassName("tooltipped"));
            },

            main_initialize: function () {
                this.materialize_init();
            }
        };

        return {
            main_init: function () {
                initializer.main_initialize();
                return this;
            }
        };
    };

    // AMD and window support
    if (typeof define === "function") {
        define([], function () { return new Initialize(); });
    } else if (typeof global.initializer === "undefined") {
        global.initializer = new Initialize();
    }

})(jQuery, this);

Let me know if it’s wrong, I just started to work with this framework today.

answered Apr 27, 2018 at 17:22

CoralK's user avatar

CoralKCoralK

3,3712 gold badges9 silver badges22 bronze badges

I am currently using this way: check jsdom’s documentation

 var html = fs.readFileSync("./your_html_file.html");

 jsdom.env({
  //url: "http://url_here", //in case you want to load specific url 
  //html property is used in case of you need to load html string here
  html: html,
  scripts: ["http://code.jquery.com/jquery.js"],
  done: function (err, window) {
    var $ = window.$;
    //start using jquery now 
    $("p").each(function(index) {
      console.log("paragraph ", index, $(this).text());
    });
  }
});

answered Oct 2, 2015 at 10:53

Muhammad Soliman's user avatar

Muhammad SolimanMuhammad Soliman

20.6k5 gold badges107 silver badges73 bronze badges

I used neoRiley’s 2 lines on node command line, and tested jQuery promises on command-line.
Added jquery to node command line via npm
//https://github.com/UncoolAJ86/node-jquery for instructions.

npm install -S 'jquery@>=2.1'
npm install -S 'jsdom@3.1.2'

/home/sridhar$ node

// make $ available on node commandline
>var jsdom = require("jsdom"); 
>var $ = require("jquery")(jsdom.jsdom().parentWindow);
>var promise = new $.Deferred();
>promise.done(function(){console.log('Starting game ..');});
>promise.resolve();

promise resolves to success callback, ‘Starting game ..’ will be printed
console output

Starting game..

answered Oct 21, 2015 at 10:40

signonsridhar's user avatar

So everything was working just fine and great until doing npm update and now things do not work quite as they used to.

A little background: in my code I use jquery to parse textual html. I do not use a window and I don’t use jsdom. It used to work just fine to do this:

$ = require("jquery"); 
$(html).find("<h1>").html("The title"); 

But now I get this:
jQuery requires a window with a document

How do I fix this?

asked Jan 26, 2014 at 0:17

Martin's user avatar

1

This worked for me

var jsdom = require('jsdom');
$ = require('jquery')(new jsdom.JSDOM().window);

Justin Geeslin's user avatar

answered Jan 18, 2018 at 11:38

Aravinthan K's user avatar

Aravinthan KAravinthan K

1,7052 gold badges19 silver badges22 bronze badges

3

The npm package for jQuery definitely used to include jsdom with it, which is why it would work at all in Node: jQuery needs to have some kind of DOM environment to work with.

You can check that old versions used to have it by doing npm install jquery@1.8.3. You’ll see jsdom being installed with it. For some reason they seem to have removed jsdom from the recent releases. I don’t know why.

However, using jsdom 7.x to run jQuery code is simple:

var jsdom = require("jsdom");
var window = jsdom.jsdom().defaultView;

jsdom.jQueryify(window, "http://code.jquery.com/jquery.js", function () {
  var $ = window.$;
  $("body").prepend("<h1>The title</h1>");
  console.log($("h1").html());
});

The path could be changed to a different version of jQuery or to a local file.

Note: Earlier versions of jsdom, including the 3.x series, would need the line var window = jsdom.jsdom().parentWindow; instead of var window = jsdom.jsdom().defaultView;. 4.x made it so that parentWindow no longer works.

answered Jan 26, 2014 at 1:09

Louis's user avatar

LouisLouis

144k28 gold badges270 silver badges314 bronze badges

0

I solved it. had to first remove jsdom and jquery then npm install jsdom jquery.

Then this:

var jsdom = require("jsdom"); 
$ = require("jquery")(jsdom.jsdom().createWindow()); 

Turns out that it was important that I had the latest version. Otherwise it didn’t work..

answered Jan 26, 2014 at 2:37

Martin's user avatar

MartinMartin

3,4453 gold badges26 silver badges30 bronze badges

2

jsdom seems to have a new version therefore now it works on a slightly different way. Here you have an example:

const { JSDOM } = require("jsdom");
const myJSDom = new JSDOM (html);
const $ = require('jquery')(myJSDom.window);

Now you can search as you used to do on jQuery:

$("<h1>").html("The title");

Mind the jQuery installation as you should write jquery all lowercase, like npm install jquery.

answered May 8, 2018 at 10:21

Hola Soy Edu Feliz Navidad's user avatar

0

You can try the following with these version settings in your package.json:

"jquery": "^2.1.1",
"jsdom": "^1.0.0-pre.3"

Say you have a file called page.htm:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>Html page</h1>
    <div class="left">
        <p>left content</p>
    </div>
</body>
</html>

Then, you can read from file, create a DOM and window from it with JSDOM and pass it to jquery:

var jsdom = require("jsdom").jsdom;
var fs = require('fs');
fs.readFile('page.htm', {encoding: "utf8"}, function (err, markup) {
  if (err) throw err;
  var doc = jsdom(markup);
  var window = doc.parentWindow;
  var $ = require('jquery')(window)
  var outerLeft = $(".left").clone().wrap('<div></div>').parent().html();
  var innerLeft = $(".left").html();
  console.log(outerLeft, "and ...", innerLeft);
});

will output:

<div class="left">
<p>left content</p>
</div> and ... 
<p>left content</p>

answered Aug 26, 2014 at 23:39

AJ Meyghani's user avatar

AJ MeyghaniAJ Meyghani

4,2891 gold badge30 silver badges35 bronze badges

0

(2018) — New jsdom API

var jsdom = require('jsdom'),
    { JSDOM } = jsdom,
    jsdom_options = {
      runScripts: "dangerously",
      resources: "usable"
    };

// external script example:
var DOM = new JSDOM(`<!DOCTYPE html><html><head><script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script></head><body></body></html>`, jsdom_options);

// local script example:
var jQuery = fs.readFileSync("../../jQuery.js", { encoding: "utf-8" });
var DOM = new JSDOM(``, { runScripts: "dangerously" });

var scriptElm = window.document.createElement("script");
scriptElm.textContent = jQuery;
DOM.window.document.head.appendChild(scriptElm);

References:

  1. Loading external scripts
  2. Loading local scripts

answered Nov 12, 2015 at 14:46

vsync's user avatar

vsyncvsync

113k55 gold badges297 silver badges382 bronze badges

0

I plopped this on the top of my Node.js (server) file that uses jQuery to help render html text …

var jsdom = require("jsdom").jsdom;
jsdom.env({
    html : "<html><body></body></html>",
    done : function(errs, window) {
        global.window = window;
    }
});

and everything comes up roses.

answered Sep 12, 2014 at 0:06

Mark Peterson's user avatar

2021 answer

Faced the same issue recently

This works with "jquery": "^3.5.1" and "jsdom": "^16.4.0"

const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const jquery = require('jquery')

getHtmlFromSomewhere(function (err, data) {
    handleError(err)
    
    console.log("html is ", data)
    const dom = new JSDOM(data);

    const $ = jquery(dom.window);
    const someData = $("#dataTable tbody tr:last td:eq(1)")

    console.log("some data is: ", someData.text())
});

The gist of the solution is parsing your HTML using JSDOM in order to obtain a window object. Then wrap said window object using jquery

And that’s it, you can use jquery selector functions in the parsed document

answered Jan 29, 2021 at 13:22

Martín Zaragoza's user avatar

You have to provide a window object. To do this, just pass parentWindow from jsdom:

var jsdom = require("jsdom"); 
var $ = require("jquery")(jsdom.jsdom().parentWindow);

answered Dec 16, 2014 at 16:53

neoRiley's user avatar

neoRileyneoRiley

4556 silver badges11 bronze badges

0

I know that I am not in the correct year here, but I may have found a better way, then the ways that offered here. If you call the scripts from the .html file, the script will know the document, and it solved the problem for me (at least for now). example:

index.html:

<html>
<head>
<meta charset="UTF-8">
<!--Scripts-->
<script>
    window.$ = window.jQuery = require('../js/libs/jQuery.js');
</script>
<script src="../js/libs/materialize.js"></script>
<script>
    const init = require("../js/initialize/initialize.js");
    init.initializer.main_init();
</script>

<!--Styles-->
<!--Libraries-->
<link rel="stylesheet" href="../scss/libs/materialize.css" />
</head>
</html>

initialize.js:

var jQuery = require('jquery');

(function($, global, undefined) {
    "use strict";

    var Initialize = function() {
        var initializer;          
        initializer = {
            materialize_init: function () {
            console.log(document.getElementsByClassName("tooltipped"));
            },

            main_initialize: function () {
                this.materialize_init();
            }
        };

        return {
            main_init: function () {
                initializer.main_initialize();
                return this;
            }
        };
    };

    // AMD and window support
    if (typeof define === "function") {
        define([], function () { return new Initialize(); });
    } else if (typeof global.initializer === "undefined") {
        global.initializer = new Initialize();
    }

})(jQuery, this);

Let me know if it’s wrong, I just started to work with this framework today.

answered Apr 27, 2018 at 17:22

CoralK's user avatar

CoralKCoralK

3,3712 gold badges9 silver badges22 bronze badges

I am currently using this way: check jsdom’s documentation

 var html = fs.readFileSync("./your_html_file.html");

 jsdom.env({
  //url: "http://url_here", //in case you want to load specific url 
  //html property is used in case of you need to load html string here
  html: html,
  scripts: ["http://code.jquery.com/jquery.js"],
  done: function (err, window) {
    var $ = window.$;
    //start using jquery now 
    $("p").each(function(index) {
      console.log("paragraph ", index, $(this).text());
    });
  }
});

answered Oct 2, 2015 at 10:53

Muhammad Soliman's user avatar

Muhammad SolimanMuhammad Soliman

20.6k5 gold badges107 silver badges73 bronze badges

I used neoRiley’s 2 lines on node command line, and tested jQuery promises on command-line.
Added jquery to node command line via npm
//https://github.com/UncoolAJ86/node-jquery for instructions.

npm install -S 'jquery@>=2.1'
npm install -S 'jsdom@3.1.2'

/home/sridhar$ node

// make $ available on node commandline
>var jsdom = require("jsdom"); 
>var $ = require("jquery")(jsdom.jsdom().parentWindow);
>var promise = new $.Deferred();
>promise.done(function(){console.log('Starting game ..');});
>promise.resolve();

promise resolves to success callback, ‘Starting game ..’ will be printed
console output

Starting game..

answered Oct 21, 2015 at 10:40

signonsridhar's user avatar

TL; DR;

В вашем случае это должно быть так же просто, как использовать;

$ = require('jquery/dist/jquery')(window);  // v2.1.0-beta2  

Это может быть очевидно; но вам придется использовать эту форму объявления (передать window в результат require) в каждом используемом вами модуле, а не только в одном/первом и т.д.


Non-TL; DR;

Для тех, кто хочет знать, почему интересный код в jQuery, который обрабатывает это,

(function( window, factory ) {

    if ( typeof module === "object" && typeof module.exports === "object" ) {
        // Expose a jQuery-making factory as module.exports in loaders that implement the Node
        // module pattern (including browserify).
        // This accentuates the need for a real window in the environment
        // e.g. var jQuery = require("jquery")(window);
        module.exports = function( w ) {
            w = w || window;
            if ( !w.document ) {
                throw new Error("jQuery requires a window with a document");
            }
            return factory( w );
        };
    } else {
        factory( window );
    }

// Pass this, window may not be defined yet
}(this, function( window ) {

    // All of jQuery gets defined here, and attached to the (locally named variable) "window".

}));

Обратите внимание на комментарии вверху, которые явно адресуют браузеру; в ситуациях, когда jQuery находится в среде CommonJs, вместо возврата jQuery, как мы его знаем, он возвращает функцию, которая при передаче объекта (который должен быть window) возвращает jQuery.


Чтобы еще больше запутать вопрос, этот код настройки снова изменился в последнем коммите, так что module.exports определяется так;

module.exports = global.document ?
    factory( global ) :
    function( w ) {
        if ( !w.document ) {
            throw new Error( "jQuery requires a window with a document" );
        }

        return factory( w );

… такое, что если this является объектом window, когда jQuery является require() ‘d, он вернет экземпляр jQuery, или, если он не вернет функцию factory, как раньше; поэтому, когда версия 2.1.0 будет выпущена, вам придется снова удалить вызов (window).

;
Date: Sat Sep 02 2017

Tags:
Node.JS »»»» Electron

What about using jQuery/Bootstrap to design an Electron app? It’s easy to get started, right? You just load the jQuery and Bootstrap JavaScript libraries in that order. The process is well documented on the Bootstrap website, and since Electron is a web browser the same technique should work. But — you get an inscrutible error that jQuery needs to be loaded. Which is odd because the HTML does indeed load jQuery, and in the Developer tools you can inspect the loaded files and see that jQuery is loaded. WTF?

The most useful way to load jQuery and Bootstrap in Electron is to install the npm modules and directly use the files in the respective dist directories. That way you’re not dependent on a 3rd party service, and are instead in control of your destiny.

In your Electron app project directory install the required modules as so:

$ npm install jquery --save
$ npm install bootstrap@4.0.0-beta --save
$ npm install popper.js --save

As of this writing Bootstrap 4 has been released as a Beta, and therefore we can install it using that tag. With Bootstrap v4 they’ve introduced Popper, which must be installed this way.

Let’s now inspect what we’ve installed:

$ ls node_modules/jquery/dist/
core.js			jquery.min.js		jquery.slim.js		jquery.slim.min.map
jquery.js		jquery.min.map		jquery.slim.min.js

$ ls node_modules/bootstrap/dist/js
bootstrap.js		bootstrap.min.js

$ ls node_modules/bootstrap/dist/css/
bootstrap-grid.css		bootstrap-reboot.css		bootstrap.css
bootstrap-grid.css.map		bootstrap-reboot.css.map	bootstrap.css.map
bootstrap-grid.min.css		bootstrap-reboot.min.css	bootstrap.min.css
bootstrap-grid.min.css.map	bootstrap-reboot.min.css.map	bootstrap.min.css.map

$ ls node_modules/popper.js/dist/umd/
popper-utils.js		popper-utils.min.js	popper.js		popper.min.js
popper-utils.js.map	popper-utils.min.js.map	popper.js.map		popper.min.js.map

Therefore, you can add this to your HTML file(s) in your Electron app.

<html>
<head>
    ... 
        <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
    ...
</head>
<body>
    ...

    <script src="../node_modules/jquery/dist/jquery.js"></script>
    <script src="../node_modules/popper.js/dist/umd/popper.js"></script>
    <script src="../node_modules/bootstrap/dist/js/bootstrap.js"></script>
</body>
</html>

That’s a straight translation of the HTML snippets in the Bootstrap installation instructions into the conditions we have in the Electron app. BTW, if you want to use the minified versions of these libraries, modify the paths to include .min.js to reference the minified files.

Start the application and you’ll see this in the JavaScript console:

Uncaught Error: Bootstrap's JavaScript requires jQuery

What’s up? Again, you can see clearly that jQuery is loaded first, and you can see clearly in the developer tools that the jQuery module was indeed loaded first.

The issue is clear once you view the source code. The jQuery library starts with this:

if ( typeof module === "object" && typeof module.exports === "object" ) {

    // For CommonJS and CommonJS-like environments where a proper `window`
    // is present, execute the factory and get jQuery.
    // For environments that do not have a `window` with a `document`
    // (such as Node.js), expose a factory as module.exports.
    // This accentuates the need for the creation of a real `window`.
    // e.g. var jQuery = require("jquery")(window);
    // See ticket #14549 for more info.
    module.exports = global.document ?
        factory( global, true ) :
        function( w ) {
            if ( !w.document ) {
                throw new Error( "jQuery requires a window with a document" );
            }
            return factory( w );
        };
} else {
    factory( global );
}

The code is a little obtuse. The effect is that if jQuery is executing in a Node.js/CommonJS environment it does not create a global jQuery object. While Electron is a Chrome browser, it also has Node.js support including the module and module.exports objects, and the require function, and so forth. Therefore when executed under Electron, jQuery runs the first branch and does not add itself to the global object, and instead exports itself via module.exports.

When Bootstrap runs, this test then fails to find jQuery because there’s no global jQuery object.

if (typeof jQuery === 'undefined') {
  throw new Error('Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.')
}

Okay, we now see the problem. When run under Node.js or Electron, jQuery doesn’t add itself to the global object. Hurm…

This is the very simple solution. Instead of loading jQuery the normal way, load it this way:

<script>
window.jQuery = window.$ = require('jquery');
</script>

<!-- <script src="../node_modules/jquery/dist/jquery.js"></script> -->

You’ll see in the developer tools JavaScript console no inscrutible error message about how jQuery must be loaded before Bootstrap.

Hat tip to:
(stackoverflow.com)
stackoverflow bootstrap-wont-detect-jquery-1-11-0-uncaught-error-bootstraps-javascript-re

About the Author(s)


(davidherron.com)
David Herron
:
David Herron is a writer and software engineer focusing on the wise use of technology. He is especially interested in clean energy technologies like solar power, wind power, and electric cars. David worked for nearly 30 years in Silicon Valley on software ranging from electronic mail systems, to video streaming, to the Java programming language, and has published several books on Node.js programming and electric vehicles.

Ezoic

Books by David Herron

(Sponsored)

  • Remove From My Forums
  • Question

  • User-110504647 posted

    Hi all,

    I´ve seen several answers to this error in Netbeans, but I really don´t know how still solve it if you please can help me here,

    i´m just starting my very first course on HTML/CSS that´s why I did not get the solutions maybe,

    Following my course, my code is exactly the same than in the course and all instructions were followed, 

    i have no errors when I check my web page via F12,

    But when I click on:

    bootstrap.min.js

    if(«undefined»==typeof jQuery)throw new Error(«Bootstrap’s JavaScript requires jQuery»)

    jquery.min

    Error(«jQuery requires a window with a document»)

    Please help!

    Thanks a lot

    Rosi

    <script src=»js/jquery.min.js»> type=»text/javascript»></script> <script src=»js/bootstrap.min.js»> type=»text/javascript»></script>

Answers

  • User839733648 posted

    Hi Rosi Q,

    According to your description and code, I’ve tested it and it works well on my side.

    Bootstrap’s JavaScript requires jQuery

    This error occurs always because you’ve not loaded the jquery.min.js before bootstrap.min.js.

    But your code is correct, I’m confused that why you have this error.

    As mgebhard has mentioned, you may check that if the relative root is correct.

    My web page looks ok but when I minimized the page the toolbar is not appearing

    Do you mean that the navbar content miss when minimizing the page?

    This is because you’ve set collapse class to button, you could move it and the button will work well.

    Here is my working code.

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Blog de Rosi</title>
        <link href="Reference/bootstrap.min.css" rel="stylesheet" />
        <script src="Reference/jquery-3.3.1.min.js"></script>
        <script src="Reference/bootstrap.min.js"></script>
    </head>
    <body>
        <nav class="navbar navbar-default navbar-static-top">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
                        <span class="sr-only">Este botón despliega la barra de navegación</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="#">Mi primer proyecto</a>
                </div>
                <div id="navbar" class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li><a href="#">Entradas</a></li>
                        <li><a href="#">Favoritos</a></li>
                    </ul>
                </div>
            </div>
        </nav>
    </body>
    </html>

    Best Regards,

    Jenifer

    • Marked as answer by

      Thursday, October 7, 2021 12:00 AM

TL; DR;

В вашем случае это должно быть так же просто, как использование;

$ = require('jquery/dist/jquery')(window);  // v2.1.0-beta2  

Это может быть очевидно; но вам придется использовать эту форму декларации (пройти window к результату require) в каждом используемом вами модуле, а не только в одном/первом и т. д.


Без TL;DR;

Для всех, кто хочет знать зачем, интересный код в jQuery, который обрабатывает это;

(function( window, factory ) {

    if ( typeof module === "object" && typeof module.exports === "object" ) {
        // Expose a jQuery-making factory as module.exports in loaders that implement the Node
        // module pattern (including browserify).
        // This accentuates the need for a real window in the environment
        // e.g. var jQuery = require("jquery")(window);
        module.exports = function( w ) {
            w = w || window;
            if ( !w.document ) {
                throw new Error("jQuery requires a window with a document");
            }
            return factory( w );
        };
    } else {
        factory( window );
    }

// Pass this, window may not be defined yet
}(this, function( window ) {

    // All of jQuery gets defined here, and attached to the (locally named variable) "window".

}));

Обратите внимание на комментарии вверху, которые явно относятся к браузеру; в ситуациях, когда jQuery находится в CommonJs-land, вместо возврата jQuery как мы знаем, он возвращает функцию, которая при передаче объекта (который должен быть window), возвращает jQuery.


Чтобы еще больше запутать дело, этот код установки снова изменился в последнем коммите, так что module.exports is определяется так;

module.exports = global.document ?
    factory( global ) :
    function( w ) {
        if ( !w.document ) {
            throw new Error( "jQuery requires a window with a document" );
        }

        return factory( w );

… такой, что если this is что собой представляет window объект, когда jQuery require()‘d, он вернет экземпляр jQuery, а если нет, то вернет фабричную функцию, как и раньше; так что когда 2.1.0 на самом деле выйдет, вам придется удалить (window) позвони снова.

Answer by Norah Jimenez

If I refresh the page for 2-3 times,error is gone.
Thanks for any help!,NodeInvocationException: Prerendering failed because of error: Error:
jQuery requires a window with a document,I’m using Angular 4 +webpack.I’ve added a jQuery plugin to nonTreeShakableModules const in webpack.config.vendor.js:,

for the moment the error has gone.i’ll keep testing.thanks

– mrapi

Oct 31 ’17 at 6:53

Replace

<my-app asp-prerender-module="ClientApp/dist/app.module.server.ts"></my-app>

with

<my-app></my-app>

Alternatively you have to run code conditionally, as pointed in this GitHub issue:

// boot-client.ts file 
import 'ngx-charts';

// some.component.ts
import { isBrowser } from 'angular2-universal';
import * as $ from 'jquery';

// inside ngOnInit 
if (isBrowser) { 
    $('body').hide();  // or whatever call you need to make
}

Answer by Bryan Dean

jQuery is a fast, small, and feature-rich JavaScript library. It makes
things like HTML document traversal and manipulation, event handling,
animation, and Ajax much simpler with an easy-to-use API that works across
a multitude of browsers. With a combination of versatility and
extensibility, jQuery has changed the way that millions of people write
JavaScript.,

jQuery in Action
Bear Bibeault, Yehuda Katz, and Aurelio De Rosa

,Supports CSS3 selectors to find elements as well as in style property manipulation,Show the #banner-message element that is hidden with
display:none in its CSS when any button in #button-container is
clicked.

$( "button.continue" ).html( "Next Step..." )

Answer by Lennox Nunez

Bootstrap 5 is designed to be used without jQuery, but it’s still possible to use our components with jQuery. If Bootstrap detects jQuery in the window object it’ll add all of our components in jQuery’s plugin system; this means you’ll be able to do $(‘[data-bs-toggle=»tooltip»]’).tooltip() to enable tooltips. The same goes for our other components.,Bootstrap will detect jQuery if jQuery is present in the window object and there is no data-bs-no-jquery attribute set on <body>. If jQuery is found, Bootstrap will emit events thanks to jQuery’s event system. So if you want to listen to Bootstrap’s events, you’ll have to use the jQuery methods (.on, .one) instead of addEventListener.,In order to execute an action once the transition is complete, you can listen to the corresponding event.,Sometimes it is necessary to use Bootstrap plugins with other UI frameworks. In these circumstances, namespace collisions can occasionally occur. If this happens, you may call .noConflict on the plugin you wish to revert the value of.

<script type="module">
  import { Toast } from 'bootstrap.esm.min.js'

  Array.from(document.querySelectorAll('.toast'))
    .forEach(toastNode => new Toast(toastNode))
</script>

Answer by Reese Anthony

Create aliases to import or require certain modules more easily. For example, to alias a bunch of commonly used src/ folders:,Redirect module requests when normal resolving fails.,Setting resolve.alias to false will tell webpack to ignore a module.,Fields in package.json that are used for resolving module requests. See package-exports guideline for more information.

webpack.config.js

module.exports = {
  //...
  resolve: {
    // configuration options
  },
};

webpack.config.js

const path = require('path');

module.exports = {
  //...
  resolve: {
    alias: {
      Utilities: path.resolve(__dirname, 'src/utilities/'),
      Templates: path.resolve(__dirname, 'src/templates/'),
    },
  },
};

Now, instead of using relative paths when importing like so:

import Utility from '../../utilities/utility';

you can use the alias:

import Utility from 'Utilities/utility';

webpack.config.js

const path = require('path');

module.exports = {
  //...
  resolve: {
    alias: {
      xyz$: path.resolve(__dirname, 'path/to/file.js'),
    },
  },
};

which would yield these results:

import Test1 from 'xyz'; // Exact match, so path/to/file.js is resolved and imported
import Test2 from 'xyz/file.js'; // Not an exact match, normal resolution takes place
module.exports = {
  //...
  resolve: {
    alias: {
      _: [
        path.resolve(__dirname, 'src/utilities/'),
        path.resolve(__dirname, 'src/templates/'),
      ],
    },
  },
};

Setting resolve.alias to false will tell webpack to ignore a module.

module.exports = {
  //...
  resolve: {
    alias: {
      'ignored-module': false,
      './ignored-module': false,
    },
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    aliasFields: ['browser'],
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    conditionNames: ['require', 'node'],
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    descriptionFiles: ['package.json'],
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    enforceExtension: false,
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    extensions: ['.js', '.json', '.wasm'],
  },
};

which is what enables users to leave off the extension when importing:

import File from '../path/to/file';

Note that using resolve.extensions like above will override the default array, meaning that webpack will no longer try to resolve modules using the default extensions. However you can use '...' to access the default extensions:

module.exports = {
  //...
  resolve: {
    extensions: ['.ts', '...'],
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    fallback: {
      abc: false, // do not include a polyfill for abc
      xyz: path.resolve(__dirname, 'path/to/file.js'), // include a polyfill for xyz
    },
  },
};

Webpack 5 no longer polyfills Node.js core modules automatically which means if you use them in your code running in browsers or alike, you will have to install compatible modules from npm and include them yourself. Here is a list of polyfills webpack has used before webpack 5:

module.exports = {
  //...
  resolve: {
    fallback: {
      assert: require.resolve('assert'),
      buffer: require.resolve('buffer'),
      console: require.resolve('console-browserify'),
      constants: require.resolve('constants-browserify'),
      crypto: require.resolve('crypto-browserify'),
      domain: require.resolve('domain-browser'),
      events: require.resolve('events'),
      http: require.resolve('stream-http'),
      https: require.resolve('https-browserify'),
      os: require.resolve('os-browserify/browser'),
      path: require.resolve('path-browserify'),
      punycode: require.resolve('punycode'),
      process: require.resolve('process/browser'),
      querystring: require.resolve('querystring-es3'),
      stream: require.resolve('stream-browserify'),
      string_decoder: require.resolve('string_decoder'),
      sys: require.resolve('util'),
      timers: require.resolve('timers-browserify'),
      tty: require.resolve('tty-browserify'),
      url: require.resolve('url'),
      util: require.resolve('util'),
      vm: require.resolve('vm-browserify'),
      zlib: require.resolve('browserify-zlib'),
    },
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    mainFields: ['browser', 'module', 'main'],
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    mainFields: ['module', 'main'],
  },
};

For example, consider an arbitrary library called upstream with a package.json that contains the following fields:

{
  "browser": "build/upstream.js",
  "module": "index"
}

webpack.config.js

module.exports = {
  //...
  resolve: {
    mainFiles: ['index'],
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    exportsFields: ['exports', 'myCompanyExports'],
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    modules: ['node_modules'],
  },
};

webpack.config.js

const path = require('path');

module.exports = {
  //...
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    unsafeCache: true,
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    unsafeCache: /src/utilities/,
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    plugins: [new DirectoryNamedWebpackPlugin()],
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    preferRelative: true,
  },
};

src/index.js

// let's say `src/logo.svg` exists
import logo1 from 'logo.svg'; // this is viable when `preferRelative` enabled
import logo2 from './logo.svg'; // otherwise you can only use relative path to resolve logo.svg

// `preferRelative` is enabled by default for `new URL()` case
const b = new URL('module/path', import.meta.url);
const a = new URL('./module/path', import.meta.url);

wepack.config.js

module.exports = {
  //...
  resolve: {
    preferAbsolute: true,
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    symlinks: true,
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    cachePredicate: (module) => {
      // additional logic
      return true;
    },
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    restrictions: [/.(sass|scss|css)$/],
  },
};

webpack.config.js

const fixtures = path.resolve(__dirname, 'fixtures');
module.exports = {
  //...
  resolve: {
    roots: [__dirname, fixtures],
  },
};

webpack.config.js

module.exports = {
  //...
  resolve: {
    importsFields: ['browser', 'module', 'main'],
  },
};
module.exports = {
  // ...
  resolve: {
    byDependency: {
      // ...
      esm: {
        mainFields: ['browser', 'module'],
      },
      commonjs: {
        aliasFields: ['browser'],
      },
      url: {
        preferRelative: true,
      },
    },
  },
};

webpack.config.js

module.exports = {
  //...
  resolveLoader: {
    modules: ['node_modules'],
    extensions: ['.js', '.json'],
    mainFields: ['loader', 'main'],
  },
};

Answer by Norah Bender

public/js/app.js: Your application code,Custom Webpack Configuration,First, install the desired plugin through NPM and include it in your array of plugins when calling Mix’s postCss method. The postCss method accepts the path to your CSS file as its first argument and the directory where the compiled file should be placed as its second argument:,Before running Mix, you must first ensure that Node.js and NPM are installed on your machine:

In other words, Mix makes it a cinch to compile and minify your application’s CSS and JavaScript files. Through simple method chaining, you can fluently define your asset pipeline. For example:

mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css');

Before running Mix, you must first ensure that Node.js and NPM are installed on your machine:

node -v
npm -v

You can easily install the latest version of Node and NPM using simple graphical installers from the official Node website. Or, if you are using Laravel Sail, you may invoke Node and NPM through Sail:

./sail node -v
./sail npm -v

The only remaining step is to install Laravel Mix. Within a fresh installation of Laravel, you’ll find a package.json file in the root of your directory structure. The default package.json file already includes everything you need to get started using Laravel Mix. Think of this file like your composer.json file, except it defines Node dependencies instead of PHP dependencies. You may install the dependencies it references by running:

npm install

Mix is a configuration layer on top of webpack, so to run your Mix tasks you only need to execute one of the NPM scripts that are included in the default Laravel package.json file. When you run the dev or production scripts, all of your application’s CSS and JavaScript assets will be compiled and placed in your application’s public directory:

// Run all Mix tasks...
npm run dev

// Run all Mix tasks and minify output...
npm run prod

The npm run watch command will continue running in your terminal and watch all relevant CSS and JavaScript files for changes. Webpack will automatically recompile your assets when it detects a change to one of these files:

npm run watch

Webpack may not be able to detect your file changes in certain local development environments. If this is the case on your system, consider using the watch-poll command:

npm run watch-poll

Tailwind CSS is a modern, utility-first framework for building amazing sites without ever leaving your HTML. Let’s dig into how to start using it in a Laravel project with Laravel Mix. First, we should install Tailwind using NPM and generate our Tailwind configuration file:

npm install

npm install -D tailwindcss

npx tailwindcss init

The init command will generate a tailwind.config.js file. Within this file, you may configure the paths to all of your application’s templates and JavaScript so that Tailwind can tree-shake unused styles when optimizing your CSS for production:

purge: [
    './storage/framework/views/*.php',
    './resources/**/*.blade.php',
    './resources/**/*.js',
    './resources/**/*.vue',
],

Next, you should add each of Tailwind’s «layers» to your application’s resources/css/app.css file:

@tailwind base;
@tailwind components;
@tailwind utilities;

Once you have configured Tailwind’s layers, you are ready to update your application’s webpack.mix.js file to compile your Tailwind powered CSS:

mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        require('tailwindcss'),
    ]);

Finally, you should reference your stylesheet in your application’s primary layout template. Many applications choose to store this template at resources/views/layouts/app.blade.php. In addition, ensure you add the responsive viewport meta tag if it’s not already present:

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link href="/css/app.css" rel="stylesheet">
</head>

First, install the desired plugin through NPM and include it in your array of plugins when calling Mix’s postCss method. The postCss method accepts the path to your CSS file as its first argument and the directory where the compiled file should be placed as its second argument:

mix.postCss('resources/css/app.css', 'public/css', [
    require('postcss-custom-properties')
]);

Or, you may execute postCss with no additional plugins in order to achieve simple CSS compilation and minification:

mix.postCss('resources/css/app.css', 'public/css');

The sass method allows you to compile Sass into CSS that can be understood by web browsers. The sass method accepts the path to your Sass file as its first argument and the directory where the compiled file should be placed as its second argument:

mix.sass('resources/sass/app.scss', 'public/css');

You may compile multiple Sass files into their own respective CSS files and even customize the output directory of the resulting CSS by calling the sass method multiple times:

mix.sass('resources/sass/app.sass', 'public/css')
    .sass('resources/sass/admin.sass', 'public/css/admin');

Because Laravel Mix is built on top of webpack, it’s important to understand a few webpack concepts. For CSS compilation, webpack will rewrite and optimize any url() calls within your stylesheets. While this might initially sound strange, it’s an incredibly powerful piece of functionality. Imagine that we want to compile Sass that includes a relative URL to an image:

.example {
    background: url('../images/example.png');
}

By default, Laravel Mix and webpack will find example.png, copy it to your public/images folder, and then rewrite the url() within your generated stylesheet. As such, your compiled CSS will be:

.example {
    background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e);
}

As useful as this feature may be, your existing folder structure may already be configured in a way you like. If this is the case, you may disable url() rewriting like so:

mix.sass('resources/sass/app.scss', 'public/css').options({
    processCssUrls: false
});

With this addition to your webpack.mix.js file, Mix will no longer match any url() or copy assets to your public directory. In other words, the compiled CSS will look just like how you originally typed it:

.example {
    background: url("../images/thing.png");
}

Though disabled by default, source maps may be activated by calling the mix.sourceMaps() method in your webpack.mix.js file. Though it comes with a compile/performance cost, this will provide extra debugging information to your browser’s developer tools when using compiled assets:

mix.js('resources/js/app.js', 'public/js')
    .sourceMaps();

Webpack offers a variety of source mapping styles. By default, Mix’s source mapping style is set to eval-source-map, which provides a fast rebuild time. If you want to change the mapping style, you may do so using the sourceMaps method:

let productionSourceMaps = false;

mix.js('resources/js/app.js', 'public/js')
    .sourceMaps(productionSourceMaps, 'source-map');

Mix provides several features to help you work with your JavaScript files, such as compiling modern ECMAScript, module bundling, minification, and concatenating plain JavaScript files. Even better, this all works seamlessly, without requiring an ounce of custom configuration:

mix.js('resources/js/app.js', 'public/js');

Mix will automatically install the Babel plugins necessary for Vue single-file component compilation support when using the vue method. No further configuration is required:

mix.js('resources/js/app.js', 'public/js')
   .vue();

Once your JavaScript has been compiled, you can reference it in your application:

<head>
    <!-- ... -->

    <script src="/js/app.js"></script>
</head>

Mix can automatically install the Babel plugins necessary for React support. To get started, add a call to the react method:

mix.js('resources/js/app.jsx', 'public/js')
   .react();

Behind the scenes, Mix will download and include the appropriate babel-preset-react Babel plugin. Once your JavaScript has been compiled, you can reference it in your application:

<head>
    <!-- ... -->

    <script src="/js/app.js"></script>
</head>

If you intend to make frequent updates to your application’s JavaScript, you should consider extracting all of your vendor libraries into their own file. This way, a change to your application code will not affect the caching of your large vendor.js file. Mix’s extract method makes this a breeze:

mix.js('resources/js/app.js', 'public/js')
    .extract(['vue'])

To avoid JavaScript errors, be sure to load these files in the proper order:

<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>

Mix provides a useful webpackConfig method that allows you to merge any short Webpack configuration overrides. This is particularly appealing, as it doesn’t require you to copy and maintain your own copy of the webpack.config.js file. The webpackConfig method accepts an object, which should contain any Webpack-specific configuration that you wish to apply.

mix.webpackConfig({
    resolve: {
        modules: [
            path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')
        ]
    }
});

The version method will append a unique hash to the filenames of all compiled files, allowing for more convenient cache busting:

mix.js('resources/js/app.js', 'public/js')
    .version();

After generating the versioned file, you won’t know the exact filename. So, you should use Laravel’s global mix function within your views to load the appropriately hashed asset. The mix function will automatically determine the current name of the hashed file:

<script src="{{ mix('/js/app.js') }}"></script>

Because versioned files are usually unnecessary in development, you may instruct the versioning process to only run during npm run prod:

mix.js('resources/js/app.js', 'public/js');

if (mix.inProduction()) {
    mix.version();
}

If your Mix compiled assets are deployed to a CDN separate from your application, you will need to change the base URL generated by the mix function. You may do so by adding a mix_url configuration option to your application’s config/app.php configuration file:

'mix_url' => env('MIX_ASSET_URL', null)

After configuring the Mix URL, The mix function will prefix the configured URL when generating URLs to assets:

https://cdn.example.com/js/app.js?id=1964becbdd96414518cd

BrowserSync can automatically monitor your files for changes, and inject your changes into the browser without requiring a manual refresh. You may enable support for this by calling the mix.browserSync() method:

mix.browserSync('laravel.test');

BrowserSync options may be specified by passing a JavaScript object to the browserSync method:

mix.browserSync({
    proxy: 'laravel.test'
});

You may inject environment variables into your webpack.mix.js script by prefixing one of the environment variables in your .env file with MIX_:

MIX_SENTRY_DSN_PUBLIC=http://example.com

After the variable has been defined in your .env file, you may access it via the process.env object. However, you will need to restart the task if the environment variable’s value changes while the task is running:

process.env.MIX_SENTRY_DSN_PUBLIC

When available, Mix will automatically display OS notifications when compiling, giving you instant feedback as to whether the compilation was successful or not. However, there may be instances when you would prefer to disable these notifications. One such example might be triggering Mix on your production server. Notifications may be deactivated using the disableNotifications method:

mix.disableNotifications();

Понравилась статья? Поделить с друзьями:
  • Throw new error in promise
  • Throw new error cheerio load expects a string
  • Throw error rust
  • Throw error laravel
  • Throw error js что это