web-dev-qa-db-fra.com

Chargement de dorsale et de soulignement à l'aide de RequireJS

J'essaie de charger Backbone et Underscore (ainsi que jQuery) avec RequireJS. Avec les dernières versions de Backbone et Underscore, cela semble un peu délicat. D'une part, Underscore s'enregistre automatiquement en tant que module, mais Backbone suppose que Underscore est disponible dans le monde entier. Je devrais aussi noter que Backbone ne semble pas s’inscrire comme un module ce qui le rend un peu incohérent avec les autres bibliothèques C'est le meilleur main.js que je pourrais trouver qui fonctionne:

require(
{
    paths: {
        'backbone': 'libs/backbone/backbone-require',
        'templates': '../templates'
    }
},
[
    // jQuery registers itself as a module.
    'http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js',

    // Underscore registers itself as a module.
    'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.2.1/underscore-min.js'
], function() {

    // These nested require() calls are just due to how Backbone is built.  Underscore basically says if require()
    // is available then it will automatically register an "underscore" module, but it won't register underscore
    // as a global "_".  However, Backbone expects Underscore to be a global variable.  To make this work, we require
    // the Underscore module after it's been defined from within Underscore and set it as a global variable for
    // Backbone's sake.  Hopefully Backbone will soon be able to use the Underscore module directly instead of
    // assuming it's global.
    require(['underscore'], function(_) {
        window._ = _;
    });

    require([
        'order!http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js',
        'order!app'
    ], function(a, app) {
        app.initialize();
    })
});

Je dois mentionner que, tant que cela fonctionne, l'optimiseur s'étouffe. Je reçois ce qui suit: 

Tracing dependencies for: main
js: "/home/httpd/aahardy/requirejs/r.js", line 7619: exception from uncaught JavaScript throw: Error: Error: Error evaluating module "undefined" at location "/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js":
JavaException: Java.io.FileNotFoundException: /home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js (No such file or directory)
fileName:/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js
lineNumber: undefined
http://requirejs.org/docs/errors.html#defineerror
In module tree:
    main

Y a-t-il une meilleure façon de gérer cela? Merci!

172
Aaronius

RequireJS 2.X s'adresse maintenant de manière organique beaucoup mieux aux modules non-AMD tels que Backbone & Underscore, en utilisant le nouveau shim configuration. 

La configuration shim est simple à utiliser: (1) on énonce les dépendances (deps), le cas échéant, (qui peuvent provenir de la configuration paths ou être des chemins valides eux-mêmes). (2) (facultatif) spécifiez le nom de la variable globale à partir du fichier que vous modifiez, qui doit être exporté vers les fonctions de module qui le nécessitent. (Si vous ne spécifiez pas les exportations, vous devrez simplement utiliser le global, car rien ne sera transmis à vos fonctions require/define.)

Voici un exemple simple d'utilisation de shim pour charger Backbone. Il ajoute également une exportation pour le soulignement, même s'il ne comporte aucune dépendance. 

require.config({
  shim: {
    underscore: {
      exports: '_'
    },
    backbone: {
      deps: ["underscore", "jquery"],
      exports: "Backbone"
    }
  }
});

//the "main" function to bootstrap your code
require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone) {   // or, you could use these deps in a separate module using define

});

Note: ce code simplifié suppose que jquery, backbone et underscore sont dans des fichiers nommés "jquery.js", "backbone.js" et "underscore.js" dans le même répertoire que ce code "principal" (qui devient le baseURL pour require). Si ce n'est pas le cas, vous devrez utiliser un chemins config .

Personnellement, je pense qu'avec la fonctionnalité shim intégrée, les avantages de ne pas utiliser une version fourchue de Backbone & Underscore l'emportent sur les avantages d'utiliser la fourche AMD recommandée dans l'autre réponse populaire, mais cela fonctionne de toute façon.

293
Ben Roberts

Update: à partir de la version 1.3.0 Suppression du support AMD (RequireJS) supprimé .

Vous pouvez utiliser amdjs/Backbone 0.9.1 et le amdjs/Underscore 1.3.1 avec le support AMD de James Burke (le responsable de RequireJS).

Plus d'infos sur support AMD pour Underscore et Backbone .

// main.js using RequireJS 1.0.7
require.config({
    paths: {
        'jquery': 'libs/jquery/1.7.1/jquery',
        'underscore': 'libs/underscore/1.3.1-amdjs/underscore', // AMD support
        'backbone': 'libs/backbone/0.9.1-amdjs/backbone', // AMD support
        'templates': '../templates'
    }
});

require([
    'domReady', // optional, using RequireJS domReady plugin
    'app'
], function(domReady, app){
    domReady(function () {
        app.initialize();
    });
});

Les modules sont correctement enregistrés et le plugin de commande n'est pas nécessaire:

// app.js
define([
    'jquery', 
    'underscore',
    'backbone'
], function($, _, Backbone){
    return {
        initialize: function(){
            // you can use $, _ or Backbone here
        }
    };
});

Le trait de soulignement est en fait facultatif, car Backbone obtient désormais ses dépendances:

// app.js
define(['jquery', 'backbone'], function($, Backbone){
    return {
        initialize: function(){
            // you can use $ and Backbone here with
            // dependencies loaded i.e. Underscore
        }
    };
});

Avec un peu de sucre AMD , vous pouvez aussi l'écrire comme ceci:

define(function(require) {
    var Backbone = require('backbone'),
        $ = require('jquery');

    return {
        initialize: function(){
            // you can use $ and Backbone here with
            // dependencies loaded i.e. Underscore
        }
    };
});

En ce qui concerne l'erreur d'optimisation: revérifiez votre configuration de construction. Je suppose que la configuration de votre chemin est désactivée. Si vous avez un configuration de répertoire similaire à la documentation RequireJS , vous pouvez utiliser:

// app.build.js
({
    appDir: "../",
    baseUrl: "js",
    dir: "../../ui-build",
    paths: {
        'jquery': 'libs/jquery/1.7.1/jquery',
        'underscore': 'libs/underscore/1.3.1-amdjs/underscore',
        'backbone': 'libs/backbone/0.9.1-amdjs/backbone',
        'templates': '../templates'
    }, 
    modules: [
        {
            name: "main"
        }
    ]
})
171
Riebel

Pour référence, à partir de la version 1.1.1 (~ février '13), Backbone également s’enregistre comme module AMD . Cela fonctionnera avec requirejs sans avoir besoin d'utiliser sa configuration de shim. ( La fourchette amdjs de James Burke n'a pas non plus été mise à jour depuis la version 1.1.0)

5
biril

Je vais écrire directement, vous pouvez lire l'explication sur requirejs.org, vous pouvez utiliser le code ci-dessous comme extrait pour votre usage quotidien; (p.s. j'utilise yeoman) (depuis de nombreuses choses mises à jour, je l'ai postée en février 2014)

Assurez-vous que vous avez inclus le script dans votre index.html

<!-- build:js({app,.tmp}) scripts/main.js -->
<script data-main="scripts/main" src="bower_components/requirejs/require.js"></script>
<!-- endbuild -->

Ensuite, dans main.js

require.config({
    shim: {
        'backbone': {
            deps: ['../bower_components/underscore/underscore.js', 'jquery'],
            exports: 'Backbone'
        }
    },

    paths: {
        jquery: '../bower_components/jquery/jquery',
        backbone: '../bower_components/backbone/backbone'
    }
});

require(['views/app'], function(AppView){
    new AppView();
});

app.js

/**
 * App View
 */
define(['backbone', 'router'], function(Backbone, MainRouter) {
    var AppView = Backbone.View.extend({
        el: 'body',

        initialize: function() {
            App.Router = new MainRouter();
            Backbone.history.start();
        }
    });

    return AppView;
});

J'espère que j'ai été utile.

4
STEEL

Bonne nouvelle, Underscore 1.6.0 prend désormais en charge les requirejs define !!!

les versions situées au-dessous de cette valeur nécessitent des cales ou des caractères de soulignement (underscore.js), espérant alors à l'aveuglette que la variable globale "_" n'a pas été brisée (ce qui est juste est un pari équitable)

chargez-le simplement par

  requirejs.config({
    paths: {
        "underscore": "PATH/underscore-1.6.0.min",
    }
  });
4
aqm
require.config({
  waitSeconds: 500,
  paths: {
    jquery: "libs/jquery/jquery",
    jqueryCookie: "libs/jquery/jquery.cookie",
    .....
  },

  shim: {
    jqxcore: {
      export: "$",
      deps: ["jquery"]
    },
    jqxbuttons: {
      export: "$",
      deps: ["jquery", "jqxcore"]
    }
    ............
  }
});

require([
 <i> // Load our app module and pass it to our definition function</i>
  "app"
], function(App) {
  // The "app" dependency is passed in as "App"
  // Again, the other dependencies passed in are not "AMD" therefore don't pass a parameter to this function
  App.initialize();
});
0
Sumesh TG