我正在使用browserify使用CommonJS样式的依赖项捆绑我的前端javascript。例如,我有:
$ = require('jquery/dist/jquery'); // v2.1.0-beta2
_ = require('underscore');
Backbone = require('backbone');
但是,当browserify将我遇到的依赖项捆绑到以下控制台错误中时:
Error: jQuery requires a window with a document
查看jQuery代码,我发现它正在尝试将this
用于全局window
。
(function( window, factory ) {
....
}(this, function( window ) {
由于browserify包装了所有依赖项,this
为object
,而不是window
。
有趣的是jQuery> = 2应该与CommonJS兼容。但是,问题是browserify如何包装依赖项。有人解决了这个问题吗?
答案 0 :(得分:20)
在您的情况下,它应该像使用一样简单;
$ = require('jquery/dist/jquery')(window); // v2.1.0-beta2
可能很明显;但是你必须在你使用的每个模块中使用这种形式的声明(将window
传递给require
的结果),而不仅仅是一个/第一个等等。
对于任何想要了解 why 的人来说,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".
}));
请注意顶部的注释明确指出browserify;在jQuery在CommonJs-land中的情况下,而不是像我们所知的那样返回jQuery
,它返回一个函数,当传递一个对象(应该是window
)时,它返回jQuery。
为了进一步混淆此事,此设置代码在最新提交中再次更改,因此module.exports
为determined like so;
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()
时,它将返回一个jQuery实例,如果不是它将像以前一样返回工厂功能;因此,当2.1.0 实际被释放时,您将不得不再次删除(window)
来电。
答案 1 :(得分:6)
var $ = require('./node_modules/jquery');
//替换来源
var jsdom = require("./node_modules/jsdom");
var window = jsdom.jsdom().createWindow();
var $ = require('./node_modules/jquery/dist/jquery')(window);
答案 2 :(得分:5)
如果您使用的是jsdom的最新版本(6.x)和最新版本的jquery(2.1.4),您可以这样做:
var $ = require('jquery')(jsdom.jsdom().defaultView);
答案 3 :(得分:4)
使用CreateWindow()的上述解决方案对我不起作用。
但是,以下内容允许我在节点中使用最新版本的JQuery:
var $ = require('jquery')(require("jsdom").jsdom().parentWindow);
答案 4 :(得分:1)
我也能像Johnny Zhao那样包括它 - 但需要首先包括jsdom。
我安装了jquery和jsdom versjon: jquery@2.2.0 node_modules \ jquery jsdom@7.2.2 node_modules \ jsdom
然后跑了:
var jsdom = require("jsdom");
var $ = require('jquery')(jsdom.jsdom().defaultView);
$("<h1>test passes</h1>").appendTo("body");
console.log($("body").html());