Javascript 使用RequireJS通过shim加载Highcharts并维护jQuery依赖关系

Javascript 使用RequireJS通过shim加载Highcharts并维护jQuery依赖关系,javascript,highcharts,requirejs,js-amd,Javascript,Highcharts,Requirejs,Js Amd,我正在尝试使用RequireJS中的垫片加载Highcharts库。然而,当Highcharts加载时,它会抛出一个异常,因为它无法访问它所依赖的jQuery方法 require配置如下所示: require.config({ baseUrl: "js", shim: { 'libs/highcharts/highcharts.src.js': { deps: ['jquery'], exports: funct

我正在尝试使用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或shimmers的人能够提供帮助,而不必太熟悉highcharts,以下是一些在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.jQuery=jQuery到垫片上的导出方法将导致highcharts拾取jQuery引用;但事实并非如此

再一次,在这一点上,任何见解、信息、建议或诘问都将不胜感激——我完全不知所措,并且开始怀疑尝试在浏览器javascript中实现AMD软件包系统是否值得


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

RequireJS使用“路径”查找不支持“AMD”的LIB,并将其加载到您的页面上。“垫片”对象允许您为路径中定义的库定义依赖项。必须先加载依赖项,然后requirejs才会尝试加载依赖脚本

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

定义完成后,可以按预期使用
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.JS
version
2.0.1


我希望有人能从中得到一些帮助;我知道这条路挡住了我一会儿;因此,我们希望通过发布此消息,避免您的头撞到墙上的同一个位置。

尽管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为何以这种方式注册感兴趣,那么更详细地说,我也遇到了同样的问题,在这里看到您的条目之前,我挣扎了好几个小时。然后我从头开始,现在它至少对我有效

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'
      }    
    },
});
由于我在主干上使用,所以我在路径属性中包含了更多的文件。Highcharts的结构与主干网相似,所以我想我可以用同样的方式加载它。它现在适合我了。正如您所看到的,我已经在路径属性中引入了highcharts,以便将其导出为一个垫片后缀


也许这会有所帮助,否则让我们尝试在这方面做出更大的贡献来解决您的问题。

我实际上下载了require.js w/jquery代码,认为这至少是“使用require.js加载jquery的建议方法”,所以这就是我正在使用的。据我所知,jQuery基本上是由require.js源代码通过使用下载来处理的,我想这应该可以消除使用“路径”来设置jQuery路径或填充jQuery的需要;谢谢你的回复!我使用
require.js2.0.1
,以防万一它很重要。Good luckI改为使用normal require.js(而不是w/jquery)并使用jquery垫片,以及您对路径/垫片的解释/示例。在阅读了更多的文档之后,现在我明白了发生了什么-非常感谢!为什么不将您的baseUrl设置为“/js/vendor/”?