web-dev-qa-db-fra.com

Façon correcte d'implémenter jQuery avec require.js

J'utilise la version stable actuelle des deux require.js et jQuery et j'inclus actuellement jQuery comme ceci

requirejs.config({
paths: {
    'jQuery': 'vendor/jquery',
}
});

require(['jQuery'], function(jQuery) {
    log(jQuery); // working
});

Ce que je ne comprends pas, c'est que je n'ai pas vraiment besoin de rendre explicitement jQuery, car cela fonctionnera toujours (également dans d'autres modules):

require(['jQuery'], function( // nothing here ) {
    log(jQuery); // working
});

Maintenant, je ne sais pas si c'est la bonne façon de le faire, également parce que l'utilisation du signe $ dollar pour la référence à jQuery ne fonctionne pas!

29
riccardolardi

Les points clés tels que je les vois:

  1. jQuery lorsqu'il est utilisé avec RequireJS s'enregistre comme module nommé 'jquery' (tout en minuscules). Dans votre exemple, vous essayez de l'utiliser comme "jQuery", ce qui embrouille un peu les choses car c'est aussi le nom d'une fonction globale qu'il enregistre lors du chargement (voir point # 2).
  2. Par défaut, jQuery s'enregistre à l'aide des fonctions globales "$" et "jQuery", même lorsqu'il est utilisé avec AMD/RequireJS. Si vous souhaitez désactiver ce comportement, vous devez appeler la fonction noConflict.
  3. Vous pouvez encapsuler votre référence RequireJS à jQuery dans un appel noConflict, comme indiqué dans l'exemple ci-dessous. Pour autant que je sache, c'est l'approche recommandée lorsque vous n'avez pas d'autres modules qui nécessitent le $ ou jQuery global:

    requirejs.config({
        paths: {
            'jquery': 'vendor/jquery',
        }
    });
    
    define('jquery-private', ['jquery'], function (jq) {
        return jq.noConflict( true );
    });
    
    require(['jquery-private'], function(jq) {
        console.log(jq);      // working
        console.log($);       // undefined
        console.log(jQuery);  // undefined
    });
    

Voir aussi ma réponse à cette question concernant la façon de mapper d'autres modules pour utiliser la version privée (noConflict).

Pour plus d'informations, consultez ces lignes du code source jQuery qui sont la cause de tout ce que j'ai décrit ci-dessus:

    // Expose jQuery to the global object
    window.jQuery = window.$ = jQuery;

    // Expose jQuery as an AMD module, but only for AMD loaders that
    // understand the issues with loading multiple versions of jQuery
    // in a page that all might call define(). The loader will indicate
    // they have special allowances for multiple jQuery versions by
    // specifying define.AMD.jQuery = true. Register as a named module,
    // since jQuery can be concatenated with other files that may use define,
    // but not use a proper concatenation script that understands anonymous
    // AMD modules. A named AMD is safest and most robust way to register.
    // Lowercase jquery is used because AMD module names are derived from
    // file names, and jQuery is normally delivered in a lowercase file name.
    // Do this after creating the global so that if an AMD module wants to call
    // noConflict to hide this version of jQuery, it will work.
    if ( typeof define === "function" && define.AMD && define.AMD.jQuery ) {
        define( "jquery", [], function () { return jQuery; } );
    }

MISE À JOUR: le tiliser avec la section jQuery du site RequireJS a été mis à jour pour refléter les informations ci-dessus. Voir aussi cette réponse pour l'optimisation étape par étape, y compris. Je veux juste souligner à nouveau que cette approche noConflict ne fonctionne que si tous vos plugins sont compatibles AMD.

39
explunit