[英]Browserify with jQuery >= 2 produces “jQuery requires a window with a document”
I'm using browserify to bundle my front-end javascript using CommonJS-style dependencies. 我正在使用browserify使用CommonJS样式的依赖项来捆绑我的前端javascript。 For example, I have:
例如,我有:
$ = require('jquery/dist/jquery'); // v2.1.0-beta2
_ = require('underscore');
Backbone = require('backbone');
However, when browserify bundles the dependencies I run into the following console error: 但是,当browserify捆绑我遇到的依赖项时,会出现以下控制台错误:
Error: jQuery requires a window with a document
Looking at the jQuery code, I see it's trying to use this
for the global window
. 看看jQuery代码,我看到它正在尝试将
this
用于全局window
。
(function( window, factory ) {
....
}(this, function( window ) {
Since browserify wraps all dependencies, this
is an object
, not the window
. 由于browserify包装了所有依赖项,
this
是一个object
,而不是window
。
What's interesting is jQuery >= 2 should be CommonJS compatible. 有趣的是jQuery> = 2应该与CommonJS兼容。 However, the problem is how browserify wraps the dependencies.
但是,问题是browserify如何包装依赖项。 Has anyone solved this problem?
有人解决了这个问题吗?
In your case, it should be as simple as using; 在你的情况下,它应该像使用一样简单;
$ = require('jquery/dist/jquery')(window); // v2.1.0-beta2
It might be obvious; 这可能是显而易见的; but you'll have to use this form of declaration (pass
window
to the result of require
) in every module you use, not just one/ the first, etc. 但是你必须在你使用的每个模块中使用这种形式的声明(将
window
传递给require
的结果),而不仅仅是一个/第一个等等。
For anyone wanting to know why , the interesting code in jQuery which handles this is; 对于任何想知道原因的人来说 ,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".
}));
Note the comments at the top which explicitly address browserify; 请注意顶部的注释明确指出browserify; in situations where jQuery is in CommonJs-land, instead of returning
jQuery
as we know it, it returns a function which, when passed an object (which should be window
), returns jQuery. 在jQuery位于CommonJs-land中的情况下,它不是像我们所知的那样返回
jQuery
,而是返回一个函数,当传递一个对象(应该是window
)时,返回jQuery。
To confuse the matter further, this setup code has changed again in the latest commit, so that module.exports
is determined like so ; 为了进一步混淆这个问题,这个设置代码在最近的提交中再次发生了变化,因此
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 );
... such that if this
is the window
object when jQuery is require()
'd, it will return a jQuery instance, or if not it'll return the factory function as before; ...这样如果
this
是 jQuery为require()
的window
对象,它将返回一个jQuery实例,如果不是,它将像以前一样返回工厂函数; so when 2.1.0 actually gets released, you'll have to remove the (window)
call again. 所以当2.1.0 实际上被释放时,你将不得不再次删除
(window)
调用。
var $ = require('./node_modules/jquery');
//replace sources //替换来源
var jsdom = require("./node_modules/jsdom");
var window = jsdom.jsdom().createWindow();
var $ = require('./node_modules/jquery/dist/jquery')(window);
如果您使用的是jsdom的最新版本(6.x)和最新版本的jquery(2.1.4),您可以这样做:
var $ = require('jquery')(jsdom.jsdom().defaultView);
The solution above with CreateWindow() did not work for me. 使用CreateWindow()的上述解决方案对我不起作用。
However, the following allowed me to get the latest version of JQuery working in node: 但是,以下允许我在节点中使用最新版本的JQuery:
var $ = require('jquery')(require("jsdom").jsdom().parentWindow);
I was also able to include it like Johnny Zhao did - but needed to include jsdom first. 我也能像Johnny Zhao那样把它包括在内 - 但需要首先包括jsdom。
I installed jquery and jsdom versjon: jquery@2.2.0 node_modules\\jquery jsdom@7.2.2 node_modules\\jsdom 我安装了jquery和jsdom versjon:jquery@2.2.0 node_modules \\ jquery jsdom@7.2.2 node_modules \\ jsdom
Then ran: 然后跑了:
var jsdom = require("jsdom");
var $ = require('jquery')(jsdom.jsdom().defaultView);
$("<h1>test passes</h1>").appendTo("body");
console.log($("body").html());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.