10

私は 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、 globalに使用しようとしていることがわかりwindowます。

(function( window, factory ) {
....
}(this, function( window ) {

browserify はすべての依存関係をラップするため、thisobjectではなくwindowです。

興味深いのは、jQuery >= 2 が CommonJS と互換性があることです。ただし、問題は、browserify が依存関係をラップする方法です。誰かがこの問題を解決しましたか?

4

5 に答える 5

20

TL;DR;

あなたの場合、それは使用するのと同じくらい簡単でなければなりません;

$ = require('jquery/dist/jquery')(window);  // v2.1.0-beta2  

明らかかもしれません。ただし、使用するすべてのモジュールで、この形式の宣言 (windowの結果に渡すrequire) を使用する必要があります。最初のモジュールだけではありません。


非TL;DR;

理由を知りたい人にとって、これを処理する 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ランドにある状況では、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 );

... jQuery が 'd のときにオブジェクトである場合this 、jQuery インスタンスを返します。そうでない場合は、以前のようにファクトリ関数を返します。そのため、2.1.0が実際にリリースされたら、呼び出しを再度削除する必要があります。windowrequire()(window)

于 2013-12-04T17:06:21.127 に答える
5

jsdom の最新バージョン (6.x) と jquery の最新バージョン (2.1.4) を使用している場合は、次のように実行できます。

var $ = require('jquery')(jsdom.jsdom().defaultView);
于 2015-10-13T05:39:26.233 に答える
4

上記の CreateWindow() を使用したソリューションは、私にとってはうまくいきませんでした。

ただし、次のようにして、ノードで動作する最新バージョンの JQuery を取得できました。

var $ = require('jquery')(require("jsdom").jsdom().parentWindow);
于 2014-09-17T00:43:52.313 に答える
1

Johnny Zhaoのように含めることもできましたが、最初にjsdomを含める必要がありました。

jquery と jsdom バージョンをインストールしました: 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());
于 2016-01-20T12:07:13.407 に答える