Side navigation
#13768 closed bug (fixed)
Opened April 12, 2013 01:24PM UTC
Closed July 04, 2013 06:03PM UTC
Last modified September 20, 2013 12:08AM UTC
Error trying to load jQuery from node.js
Reported by: | gleb.bahmutov@gmail.com | Owned by: | timmywil |
---|---|---|---|
Priority: | high | Milestone: | 2.1 |
Component: | build | Version: | 2.0.0-beta3 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
Trying to load jquery from a small node.js script
var $ = require('./jquery');
Using latest build (e80117adb49eff8f82140b01d755bdeefe7eb089) and
building using grunt gives:
L:\\tests\\node-test\\jquery.js:8764 })( window ); ^ ReferenceError: window is not defined at Object.<anonymous> (L:\\tests\\node-test\\jquery.js:8764:5) at Module._compile (module.js:456:26)
Using official 2.0.0-beta3 gives slightly different error (because the top level object passed into the IIFE was this, not window)
L:\\tests\\node-test\\jquery-2.0.0-beta3.js:35 docElem = document.documentElement, ^ TypeError: Cannot read property 'documentElement' of undefined at L:\\tests\\node-test\\jquery-2.0.0-beta3.js:35:20 at Object.<anonymous> (L:\\tests\\node-test\\jquery-2.0.0-beta3.js:8764:3)
Attachments (0)
Change History (20)
Changed April 12, 2013 02:22PM UTC by comment:1
owner: | → rwaldron |
---|---|
status: | new → assigned |
Changed April 12, 2013 04:11PM UTC by comment:2
This is what we expected. jQuery is not meant to be loaded with Node alone as it doesn't work without the DOM. It needs something like jsdom to export a window object. That being said, we could provide limited support by doing window || this
in the outro, but we couldn't guarantee it's functionality.
Changed April 12, 2013 05:54PM UTC by comment:3
I doubt it would get very far even if window
was defined as this
. We're not trying to make jQuery work standalone in the Node environment, just to make it more convenient to use as a module with things like jsdom. I'll explain that a bit better in the next blog announcement.
Just a thought ... what if we defined the exports like this so window
didn't have to be global? Makes the invocation more error prone but would emphasize the dependency.
module.exports = function( w ){ // If user passed in a window object, use it; // otherwise keep using the IIFE window variable if ( w ) { window = w; } ... } ... // User should do the require like this, passing in a // suitably faked but functional window object. var $ = require( "jquery" )( window );
Changed April 12, 2013 06:24PM UTC by comment:4
I agree that having window in general, maybe better error message?
In my case I wanted to use jQuery deferred from node.
Changed April 12, 2013 06:29PM UTC by comment:5
@gleb, in that case you want this: https://github.com/jaubourg/jquery-deferred-for-node
Changed April 12, 2013 06:36PM UTC by comment:6
component: | unfiled → build |
---|---|
priority: | undecided → high |
Good idea Dave. I'd prefer to pass the right window to the IIFE. Maybe something like this:
Changed April 12, 2013 07:35PM UTC by comment:7
@timmywill Seems like a reasonable solution*, but I still want Domenic to chime in.
Changed April 13, 2013 12:22AM UTC by comment:8
Passing window || this
instead of window
to IIFE would still break in the very beginning, on location = window.location
in core.js:13 so this solves nothing really.
It's probably better to wait for Domenic on this instead of second-guessing how would people actually use it, though I like the last proposed idea.
Changed May 07, 2013 02:23PM UTC by comment:9
I've emailed Domenic.
Changed May 07, 2013 02:25PM UTC by comment:10
owner: | rwaldron → timmywil |
---|
I'll go ahead and take this one and follow up later.
Changed May 07, 2013 02:56PM UTC by comment:11
I think jQuery should stay as it is in 2.0. In particular, I think the proposed var $ = require( "jquery" )( window )
idea is bad.
The use case that's most important, in my opinion, is people using browserify or one of the many other CommonJS-in-the-browser systems. For those people, they just want var $ = require("jquery")
to work; they don't want to pass in window
, or even let defaults take over and do var $ = require("jquery")()
.
Another consideration is that jQuery should present a uniform interface to all module systems. AMD and the global-object "module system" both present jQuery as the $
function. Presumably when ES6 modules start coming to browsers, jQuery will do the same for those. CommonJS should be no different.
Note that in jsdom, jQuery is always run within the context of a global environment that has a window
anyway, so that use case also wants the usual jQuery behavior. The proposed var $ = require("jquery")(window)
would be a nice convenient syntax in some cases, but would break all cases that try to use jQuery as it exists today, as something that relies on window
as an ambient variable.
Perhaps the best of both worlds, *if* this is an important use case, would be
// works in browserify etc., throws in Node.js
// unless of course you do
.
var $ = require("jquery");
// for convenient jsdom/Node.js usage:
var window = jsdom.createWindow();
var $ = require("jquery").fromWindow(window);
But again I don't think this is terribly important; given the focus on byte-saving around here, I can't imagine it would pass muster.
Changed May 07, 2013 03:30PM UTC by comment:12
@domenic: Sounds reasonable. One minor note.
We probably couldn't provide something like .fromWindow
unless we did an early return where no window was available (in which case require("jquery")
would not return anything except some object containing .fromWindow
. That's already pretty ugly as the export would again be inconsistent. Judging from your comment as a whole, it seems the best solution is to leave 2.0 the way it is and suggest defining the window globally before requiring jQuery.
Changed May 08, 2013 04:00PM UTC by comment:13
@timmywil yeah, I wasn't sure how much initialization require("jquery")
would do. In theory since $
is just a function, it could be no initialization, right? So window
wouldn't actually be used until you called the function, e.g. $(".whatever")
or $("<div>")
. But I imagine in reality things are more complicated.
Changed May 08, 2013 04:06PM UTC by comment:14
@domenic We do some support tests at the time of loading. Also, there's some initial caching going on (like location = window.location
) amongst other things so, yeah, it's not so simple.
Changed May 08, 2013 04:19PM UTC by comment:15
resolution: | → wontfix |
---|---|
status: | assigned → closed |
Closing wontfix, but we should document this somewhere. Opened api issue https://github.com/jquery/api.jquery.com/issues/296
Changed June 12, 2013 09:35PM UTC by comment:16
resolution: | wontfix |
---|---|
status: | closed → reopened |
I think we should discuss this further. Julian proposed having a custom build for NPM.
Changed June 12, 2013 09:35PM UTC by comment:17
status: | reopened → assigned |
---|
Changed June 27, 2013 03:14AM UTC by comment:18
@domenic: Knowing that jQuery needs a window at initialization time, is this looking any better to you?
https://github.com/timmywil/jquery/compare/13768
Bottom line is jQuery can't be included (not just used) without a window, so making that explicit in the require call makes sense to me.
Changed July 04, 2013 06:03PM UTC by comment:19
Changed September 20, 2013 12:08AM UTC by comment:20
milestone: | None → 2.1 |
---|
Yep, that sounds about right...
http://bugs.jquery.com/ticket/13760