Подтвердить что ты не робот

Загрузка Highcharts с помощью прокладки с использованием RequireJS и поддержка зависимости jQuery

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

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

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

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

Чтобы добавить дополнительный контекст, в надежде, что кто-то, кто знаком с require.js или прокладками, сможет помочь, не будучи слишком близко знакомым с 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 в начале script. Таким образом, я думал, что добавление метода window.jQuery = jQuery; к методу экспорта на прокладке приведет к тому, что высокие диаграммы собирают ссылку jQuery; но это не так.

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


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

RequireJS использует "пути" для поиска libs, которые не поддерживаются "AMD" и загружают их на вашу страницу. объект "shim" позволяет вам определять зависимости для библиотек, определенных в путях. Загрузки должны быть загружены до того, как requirejs попытается загрузить зависимый script.

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

Как только ваши определения будут выполнены, вы можете использовать функцию requirejs 'define, как ожидалось.

Здесь мой пример require.config object:

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.

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

4b9b3361

Ответ 1

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

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'
      }    
    },
});

Поскольку я использую Chaplin поверх Backbone, я включаю еще несколько файлов в свой атрибут paths. Highcharts имеет аналогичную структуру для Backbone, поэтому я думал, что смогу загрузить ее таким же образом. Теперь это работает для меня. Как вы можете видеть, я вводил высокоуровневые атрибуты paths, чтобы экспортировать их как временные слова прокладки.

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

Ответ 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 регистрируется таким образом, то в источнике есть довольно большой комментарий, который более подробно рассмотрен