19

我正在尝试使用 RequireJS 中的垫片加载 Highcharts 库。但是,当 Highcharts 加载时,它会抛出异常,因为它无法访问它所依赖的 jQuery 方法。

要求配置如下所示:

require.config({
    baseUrl: "js",

    shim: {

        'libs/highcharts/highcharts.src.js': {
            deps: ['jquery'],
            exports: function(jQuery)
            {
                this.HighchartsAdapter = jQuery;

                return this.Highcharts;
            }
        }
    }
});

抛出的异常是:

Uncaught TypeError: undefined is not a function

并且关于这条线:

dataLabels: merge(defaultLabelOptions, {

问题在于merge调用,它最终将自身映射回 jQuery(或 Highcharts 支持的其他适配器;但我只是使用 jQuery)。

我不确定如何确保 Highcharts 可以使用 RequireJS 和 shim 访问 jQuery。

有没有人一起使用过 RequireJS 和 Highcharts ?我猜这个问题并不特定于 highcharts,而是任何具有其他类型依赖项的库。

在此先感谢您提供任何建议或指出正确的方向!

为了添加更多上下文,希望熟悉 require.js 或 shims 的人能够提供帮助而不必非常熟悉 highcharts,这里有一些merge在 Highcharts 中设置此方法的源

var globalAdapter = win.HighchartsAdapter,
adapter = globalAdapter || {},

// Utility functions. If the HighchartsAdapter is not defined, 
// adapter is an empty object
// and all the utility functions will be null. In that case they are 
// populated by the
// default adapters below.

// {snipped code}

merge = adapter.merge

// {snipped code}

if (!globalAdapter && win.jQuery) {
    var jQ = win.jQuery;

    // {snipped code}

    merge = function () {
        var args = arguments;
        return jQ.extend(true, null, args[0], args[1], args[2], args[3]);
    };

    // {snipped code}
}

该对象是在脚本开头win设置的引用。window所以,我认为window.jQuery = jQuery;在 shim 上添加导出方法会导致 highcharts 获取 jQuery 参考;但事实并非如此。

同样,在这一点上,任何见解、信息、建议或质问都会受到赞赏 - 我完全不知所措,并开始质疑尝试在浏览器 JavaScript 中实现 AMD 软件包系统是否值得。


在接受了下面pabera的答案后,我认为更新我的问题以反映他的答案如何帮助我的解决方案是合适的(不过,这基本上是他的答案)。

RequireJS 使用“路径”来查找不受“AMD”支持的库并将它们加载到您的页面上。“shim”对象允许您为路径中定义的库定义依赖项。必须在 requirejs 尝试加载依赖脚本之前加载依赖项。

export 属性提供了一种机制来告诉 requirejs 如何确定是否加载了库。对于 jquery、backbone、socketio 等核心库,它们都导出一些窗口级别变量(Backbone、、iojQuery$)。您只需提供该变量名作为exports属性,requirejs 将能够确定何时加载 lib。

完成定义后,您可以按预期使用requirejs'函数。define

这是我的示例require.config对象:

require.config({
    baseUrl: "/js/",

    paths: {
        jquery: 'jquery',
        socketio: 'http://localhost:8000/socket.io/socket.io', //for loading the socket.io client library
        highcharts: 'libs/highcharts/highcharts.src',
        underscore: 'libs/underscore',
        backbone: 'libs/backbone'
    },

    shim: {
        jquery: {
            exports: 'jQuery'
        },

        socketio: {
            exports: 'io'
        },

        underscore: {
            exports: '_'
        },

        backbone: {
            deps: ['jquery', 'underscore'],
            exports: 'Backbone'
        },

        highcharts: {
            deps: ['jquery'],
            exports: 'Highcharts'
        }
    }
});

正如pabera之前提到的,这是针对Require.JSversion的2.0.1

我希望有人能从中得到一些用处;我知道这条路挡住了我一会儿;所以希望我们通过发布这个来防止你把你的头撞到我们所做的墙上的同一个地方。

4

2 回答 2

28

我遇到了完全相同的问题,我挣扎了好几个小时,直到我在这里看到你的条目。然后我从头开始,现在它至少对我有用。

requirejs.config({
    baseUrl:'/js/',
    paths:{
      jquery:'vendor/jquery',
      handlebars: 'vendor/handlebars',
      text: 'vendor/require-text',
      chaplin:'vendor/chaplin',
      underscore:'vendor/underscore',
      backbone:'vendor/backbone',
      highcharts: 'vendor/highcharts'
    },

    shim: {
      backbone: {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
      },
      underscore: {
        exports: '_'
      },    
      highcharts: {
        exports: 'Highcharts'
      }    
    },
});

由于我在 Backbone 之上使用卓别林,我在我的路径属性中包含了更多文件。Highcharts 与 Backbone 有相似的结构,所以我想我可以用同样的方式加载它。它现在对我有用。如您所见,我已经在 paths 属性中引入了 highcharts 以将其导出为 shim 后缀。

也许这会有所帮助,否则让我们尝试为它做出更多贡献以解决您的问题。

于 2012-06-12T12:17:58.987 回答
2

尽管 jQuery 可以用作 AMD 模块,但它仍然会将自身导出到窗口,因此任何依赖于全局的脚本,jQuery或者$只要 jQuery 首先加载,它仍然可以工作。

您是否尝试过设置路径?jQuery 是一个有趣的工具,因为尽管 RequireJS 文档鼓励您不要为模块命名,但实际上 jQuery 确实如此。

来自 jQuery 源

if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
    define( "jquery", [], function () { return jQuery; } );
}

这意味着您需要告诉 RequireJS 在哪里可以找到“jquery”。所以:

require.config({
    paths: {
        'jquery': 'path/to/jquery'
    }
});

如果您对为什么 jQuery 以这种方式注册自己感兴趣,那么源代码中有一个相当大的注释,其中包含更多详细信息

于 2012-06-06T12:42:15.363 回答