Иногда ни по какой причине jQuery не загружается с require.js

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

Обычно это работает очень хорошо, но иногда происходит сбой. Там мой файл app.js. Все мои файлы "modules" имеют jQuery в качестве зависимости в функции "define".

require.config({
    baseUrl: 'js/', // '../Style%20Library/js/' pour Sharepoint
    paths: {
        jquery: 'vendor/jquery-1.11.2.min',
        jqueryui: 'vendor/jquery-ui',
        jrespond: 'vendor/jrespond-0.10',
        transit: 'vendor/jquery.transit.min',
        easing: 'vendor/jquery.easing.1.3',
        mainMenu: 'modules/main-menu',
        resBreakpoints: 'modules/resBreakpoints'
        [...]
    }
});

require(['jquery','resBreakpoints', 'transit'], function($, resBreakpoints, transit) {
    // Support aux vieux browser pour ne pas utiliser le plugin transition
    if(!Modernizr.csstransitions){ 
        $.fn.transition = $.fn.animate; 
    }
});

Что может вызвать аварию? Когда это работает, в консоли нет ошибок, но когда происходит сбой, она показывает эту ошибку для многих модулей.

Uncaught ReferenceError: jQuery не определен

Когда jQuery не определен, jQuery и другие файлы полностью загружены, на вкладке сети нет ошибок.

Спасибо за помощь!

1 ответ

Решение

jQuery и ряд других библиотек - некоторые старые и некоторые просто непреклонные, чтобы избежать современных соглашений (кашель Backboneкашель) - не поддерживают загрузчики модулей любого рода. Чтобы загрузить те с помощью require, вам нужно использовать функцию shims и явно перечислить символы, которые экспортирует модуль. Вы можете увидеть пример здесь, в моем шаблонном проекте и выделенном ниже:

require.config({
    shim: {
      jquery: {
        exports: '$'
      }
    }
  });

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

При использовании jQuery из другого кода, убедитесь, что вы либо:

  • требовать от других модулей или
  • требует, прежде чем что-то загружает

Для чистоты я предпочитаю первое. С данной прокладкой вам нужно require('jquery') в начале каждого модуля, а не require('$') или что-нибудь в этом роде. Имя (ключ) шимма - это имя модуля оттуда и делает var $ = require('jquery') вернет нужный вам символ.

Для удобства чтения и самостоятельного документирования я предпочитаю использовать имя библиотеки в качестве имени шим (jquery, underscore, lodash) и импортируйте его в область видимости, используя символ ($ или же _), а не с именем модуля, состоящего не из одного символа. Это личное предпочтение, я считаю, но довольно ясно, что

import $ from 'jquery';

делает.

Если у вас есть плагины jQuery или вы используете Twitter Bootstrap, вам может понадобиться определить другие прокладки, которые зависят от вашего нового jQuery-модуля. Это вынуждает jQuery загружаться перед плагином, по существу перечисляя дерево зависимостей для require независимо от самих модулей. Мой пример Bootstrap должен работать и для плагинов jQuery:

shim: {
  bootstrap: {
    deps: ['jquery']
  }
}

Это вызывает зависимости между модулями, что позволяет вам require плагин и будьте уверены, что родители будут загружены ранее. Поскольку jQuery и тому подобное помещают свои символы в глобальную область видимости, вам не нужно настраивать импорт в плагины, просто убедитесь, что библиотека была необходима, прежде чем плагин начнет загружаться.

Другие вопросы по тегам