Вопрос по javascript – Загрузка Highcharts через shim с использованием RequireJS и поддержание зависимости jQuery

19

Я пытаюсь загрузить библиотеку Highcharts, используя прокладку в RequireJS. Однако, когда загружаются 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 call, который в конечном итоге отображает себя обратно в jQuery (или в другой адаптер, поддерживаемый Highcharts; но я просто использую jQuery).

Я не уверен, как именно убедиться, что Highcharts получает доступ к jQuery с помощью RequireJS и shim.

Кто-нибудь раньше использовал RequireJS и Highcharts вместе? Я предполагаю, что проблема не является специфичной для старших диаграмм, но для любой библиотеки, которая имеет другие виды зависимостей.

Заранее спасибо за любые советы или указывает на правильное направление!

To add further context, in hopes that someone who is familiar with require.js or shims will be able to help without having to be too intimately familiar with highcharts, here's some source that sets up this merge method in 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 привел к тому, что старшие диаграммы получат ссылку на jQuery; но это не так.

Опять же, любая оценка, информация, совет или хеклс были бы оценены в этот момент - я в полной растерянности и начинаю сомневаться, стоит ли пытаться реализовать систему пакетов AMD в браузерном javascript.


После принятия ответа отpabera ниже я счел целесообразным обновить мой вопрос, чтобы отразить, как его ответ помог моему решению (хотя, в основном, это его ответ).

RequireJS использует & quot; пути & quot; чтобы найти библиотеки, которые не являются "AMD"; поддерживается и загружает их на вашей странице. «шим» Объект позволяет вам определять зависимости для библиотек, определенных в путях. Зависимости должны быть загружены до того, как requirejs попытается загрузить зависимый скрипт.

Свойство exports предоставляет механизм для указания requirejs, как определить, загружена ли библиотека. Для основных библиотек, таких как jquery, backbone, socketio и т. Д., Все они экспортируют некоторую переменную уровня окна (Backbone, io, jQuery а также$, так далее). Вы просто предоставляете это имя переменной какexports свойство, а requirejs сможет определить, когда загружена библиотека.

Как только ваши определения сделаны, вы можете использоватьrequirejs& APOS;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 версия2.0.1.

Я надеюсь, что кому-то это пригодится; Я знаю, что дорога заблокировала меня на некоторое время; надеюсь, мы не дали вам ударить головой о то же место на стене, что и мы, разместив это.

Ваш Ответ

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, я включаю еще несколько файлов в свой атрибут paths. Highcharts имеет структуру, аналогичную Backbone, поэтому я подумал, что могу загрузить ее таким же образом. Это работает для меня сейчас. Как вы можете видеть, я уже ввел высокие атрибуты в атрибут paths, чтобы экспортировать его в качестве промежуточных слов.

Возможно, это поможет, в противном случае давайте попытаемся внести в него еще больший вклад в решение вашей проблемы.

Error: User Rate Limit Exceeded Jim Rubenstein
Error: User Rate Limit Exceededrequire.js 2.0.1Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Jim Rubenstein
Error: User Rate Limit Exceeded
2

он все равно будет экспортироваться в окно, поэтому любые сценарии зависят от глобальногоjQuery или же$ будет работать до тех пор, пока jQuery загрузится первым.

Вы пытались установить путь? jQuery интересен тем, что, хотя вы и не рекомендовали называть свои модули документацией RequireJS, jQuery фактически делает это.

From the jQuery source

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

Это означает, что вам нужно будет указать RequireJS, где найти «jquery». Так:

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

Если вы заинтересованы в том, почему jQuery регистрируется таким образом, тогдав источнике есть довольно большой комментарий что более подробно

Error: User Rate Limit ExceededhereError: User Rate Limit Exceeded Jim Rubenstein

Похожие вопросы