Comment débuter avec RequireJS

Require.JS

L’AMD (Asynchronous Module Definition) permet d’organiser votre code en modules afin de pouvoir les charger à la demande. Cela évite d’avoir un seul gros fichier ou plusieurs fichiers à inclure dans le HTML dans un ordre précis.

RequireJS permet également, grâce à NodeJS, de faire de l’optimisation (minification), j’en parlerai à la fin.

Vous pouvez retrouver les fragments de code contenus dans ce guide sur GitHub. N’hésitez pas à télécharger la source et la bidouiller. C’est un bon moyen de tester.

Utilisation basique (Chargement de fichiers)

  • Télécharger la dernière version stable de RequireJS sur le site ou sur GitHub.
  • Inclure RequireJS dans la page HTML en renseignant l’attribut data-main avec le chemin de votre fichier principal, pour l’exemple j’ai choisi app/main.js.

index.html

<script data-main="app/main" src="libs/require.js"></script>

RequireJS considère que la racine de votre application est le répertoire contenant le fichier main, donc app/ dans notre cas. Ce paramètre (baseUrl) peut être modifié manuellement, nous verrons ça plus tard dans l’article.

  • Créer le fichier main.js qui va contenir la configuration de RequireJS et généralement, l’initialisation de notre application. Pour l’exemple nous allons inclure 1 module : app.js qui se trouve dans le répertoire app/.

main.js

// main.js est chargé automatiquement grâce à
// l'attribut data-main dans la balise script de require.js
require([
    'app', // app/app.js
], function(App) {
    // Callback executé une fois app.js chargé
    App.initialize();
});

Définir des modules

Dans notre exemple ci-dessus, nous chargeons app.js afin d’appeler la fonction initialize() de ce module. Nous allons voir comment définir ce module :

app.js

define([
    'random_lib' // Charge le module app/random_lib.js
], function(randomLib) {

    function initialize() {
        // Initialization stuff
        randomLib.randomStuff();
    }

    // On exporte la fonction initialize dans le module app.js
    return {
        initialize: initialize
    };

});

Une autre syntaxe est possible si vous n’avez pas de dépendances à charger :

define(function() {

    function initialize() {
        // Initialization stuff
    }

    return {
        initialize: initialize
    };

});

RequireJS + jQuery

logo-jquery

Le concepteur de RequireJS a eu la bonne idée de créer un bundle RequireJS 2.x + jQuery 1.8.x : require-jquery, vous n’êtes pas obligé de passer par là pour inclure jQuery dans votre projet mais cela permet d’éviter les éventuels conflits de chargement de plugins jQuery.

De plus require-jquery est livré avec un projet d’exemple afin de regarder un peu comment ça fonctionne.

Exemple d’utilisation

define([
    'jquery'
],function($){

    $(function(){
        $("body").append("Hello World");
    });

});

Charger des templates à la volée

A l’aide du plugin text de RequireJS vous pouvez également charger vos templates HTML.

  • Télécharger le plugin et le copier à la racine (baseUrl) définie par RequireJS (pour notre exemple c’est app/)
  • Rajouter simplement text! devant le nom du fichier à inclure, le plugin fera le reste.
require([
    "underscore",
    "text!templates/module.html" // app/templates/module.html
], function(_, html) {
    // vous retrouvez ici votre template
    // que vous pouvez compiler par exemple avec underscore
    var compiledTemplate = _.template(html);
});

Il reste quelques options à découvrir, je vous conseille de lire la doc si vous souhaitez utiliser ce plugin.

Configuration avancée

Dans le fichier main (dans l’exemple app/main.js) il est possible de configurer RequireJS.

Base URL

Le paramètre baseUrl permet de modifier la racine assignée par défaut.

Les paths

Les paths permettent de rajouter vos propres chemins personnalisés vers vos modules et assets, c’est pratique si vous voulez sortir de baseUrl ou faire des raccourcis.

main.js

require.config({
    paths: {
        libs: '../libs'
    }
});

Ce path vous permettra de charger des fichiers dans le repertoire ../libs de cette manière :

require(['libs/underscore'], function(_){ });

Les shims

Les shims sont utiles si vous souhaitez utiliser des libs qui ne sont pas supportées par l’AMD.

Par exemple si vous voulez utiliser Backbone en tant que module RequireJS :

main.js

requirejs.config({
    shim: {
        'backbone': {
            // Liste des dépendences
            deps: ['underscore', 'jquery'],
            // Exporte la variable globale 'Backbone' en tant que module
            exports: 'Backbone'
        }
    }
});

Autres options

Je vous conseille de parcourir la documentation de RequireJS pour vous faire une idée de toutes les possibilités.

Optimiser et minifier

RequireJS propose un outil d’optimisation. Pour l’utiliser il vous faut une version de NodeJS supérieure à 0.4.0.

Pour l’installer avec npm :

npm install -g requirejs

Ensuite il faut créer un fichier de configuration :

build.js

({
    // Répertoire du fichier main
    baseUrl: "app/",
    // Ne pas oublier de rajouter le chemin de jQuery
    paths: { "jquery": "../libs/require-jquery" },
    // Nom du fichier main
    name: "main",
    // Nom du fichier qui sera généré après optimisation
    out: "main-built.js"
})

Puis il n’y a plus qu’à utiliser la ligne de commande suivante :

r.js -o build.js

De nombreuses options sont disponibles, je vous invite à consulter la documentation dédiée.

Quelques ressources pour aller plus loin

C’est la fin de ce petit Getting Started, j’espère qu’il aura éclairé certains d’entre vous. Si vous avez des remarques, des questions ou si vous avez trouvé des informations erronées (ça peut arriver), n’hésitez pas m’en faire part dans les commentaires. Je mettrai à jour cet article en fonction des demandes.

6 thoughts on “Comment débuter avec RequireJS”

  1. À quoi sert deps et exports dans la conf ?
    Dans tous les cas, si on déclare backbone avec en deps jquery et underscore, nous devons les mettre dans les defines du fichier qui utilisera backbone.

    L’article est très cool, c’est une bonne approche que j’ai pu découvrir seul il y a peu de temps, j’aurais gagné du temps en lisant cet article le jour ou j’ai découvert requirejs.

    1. Les deps dans les shims servent à s’assurer que les dépendances d’une lib qui n’utilise pas l’amd sont bien chargées avant de charger la lib.

      Par exemple pour Backbone, le shim :

      requirejs.config({
          shim: {
              'backbone': {
                  // Liste des dépendences
                  deps: ['underscore', 'jquery'],
                  // Exporte la variable globale 'Backbone' en tant que module
                  exports: 'Backbone'
              }
          }
      });
      

      Ça revient à faire une sorte de Wrapper au dessus de Backbone qui ferait :

      define(["jquery", "underscore"], function($, _) {
          
          // Le code de Backbone
          
          return Backbone;
      });
      

Leave a Reply

Your email address will not be published. Required fields are marked *