使用RequireJS通过填充程序加载Highcharts并保持jQuery依赖性

时间:2012-06-06 02:40:12

标签: javascript highcharts requirejs js-amd

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

require配置如下:

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或垫片的人能够提供帮助,而不必过于熟悉高级图表,这里有一些来源设置此{{1} Highcharts中的方法

merge

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添加到shim上的export方法会导致highcharts获取jQuery引用;但它没有。

此外,任何洞察力,信息,建议或哎呀都会受到赞赏 - 我完全失去了,并开始质疑是否尝试在浏览器javascript中实现和AMD软件包系统是值得的。< / p>


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

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

exports属性提供了一种机制来告诉requirejs如何确定是否加载了库。对于像jquery,backbone,socketio等核心库,它们都会导出一些窗口级变量(window.jQuery = jQuery;BackboneiojQuery等。您只需将该变量名称作为$属性提供,并且requirejs将能够确定何时加载lib。

完成定义后,您可以按预期使用exports'requirejs功能。

这是我的示例define对象:

require.config

如前所述 pabera ,这适用于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' } } }); 版本Require.JS

我希望有人可以使用它;我知道这条路阻挡了我一会儿;所以我们希望通过张贴这个来阻止你把我的头撞到墙上的同一个地方。

2 个答案:

答案 0 :(得分: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之上使用Chaplin,因此我在路径属性中包含了更多文件。 Highcharts与Backbone有类似的结构,所以我想我可以用同样的方式加载它。它现在对我有用。正如您所看到的,我在paths属性中引入了highcharts,将其导出为shim afterwords。

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

答案 1 :(得分: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以这种方式注册的原因感兴趣,那么there is a pretty large comment in the source会更详细地说明