我正在使用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如何包装依赖项.有人解决了这个问题吗?
在你的情况下,它应该像使用一样简单;
$ = require('jquery/dist/jquery')(window); // v2.1.0-beta2
这可能是显而易见的; 但是你必须在你使用的每个模块中使用这种形式的声明(传递window
给结果require
),而不仅仅是一个/第一个,等等.
对于任何想知道原因的人来说,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
被确定像这样 ;
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的情况下,如果没有它会像以前那样返回工厂函数; 所以当2.1.0 实际上被释放时,你将不得不(window)
再次删除该呼叫.
var $ = require('./node_modules/jquery');
//替换来源
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);