[英]Browserify with jQuery >= 2 produces “jQuery requires a window with a document”
我正在使用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
是 jQuery為require()
的window
對象,它將返回一個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);
使用CreateWindow()的上述解決方案對我不起作用。
但是,以下允許我在節點中使用最新版本的JQuery:
var $ = require('jquery')(require("jsdom").jsdom().parentWindow);
我也能像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());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.