Browserify with jQuery> = 2产生"jQuery需要一个带文档的窗口"

 壹滒_918 发布于 2023-02-12 19:48

我正在使用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如何包装依赖项.有人解决了这个问题吗?

3 个回答
  • 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-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)再次删除该呼叫.

    2023-02-12 19:50 回答
  • var $ = require('./node_modules/jquery');
    

    //替换来源

    var jsdom = require("./node_modules/jsdom");
    var window = jsdom.jsdom().createWindow();
    var $ = require('./node_modules/jquery/dist/jquery')(window);
    

    2023-02-12 19:50 回答
  • 如果您使用的是jsdom的最新版本(6.x)和最新版本的jquery(2.1.4),您可以这样做:

    var $ = require('jquery')(jsdom.jsdom().defaultView);
    

    2023-02-12 19:51 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有