61 votes

Comment réaliser un chargement paresseux avec RequireJS?

Nous allons construire une non-trival application web à l'aide de la Dorsale, RequireJS et le Guidon, et bien, je suis juste curieux. À l'heure actuelle, chacun de nos modèles sorta ressemble à ceci:

define(['Backbone', 'js/thing/a', 'js/thing/b', 'js/lib/bob'], function(a, b, bob) {
  return Backbone.Router.extend({
    // stuff here
  });
});

où la chose/une chose/b disposent de leurs propres dépendances, par exemple sur les poignées des modèles, etc. Ce qui se passe maintenant c'est que dans ma main.js tous les "haut-niveau" routeurs sont chargé et initialisé; chaque haut-niveau routeur dispose d'un ensemble de dépendances (modèles, vues, etc) qui ont chacun leurs propres dépendances (modèles, des assistants, utils, etc). Fondamentalement, un grand arbre de la structure.

Le problème dans ce cas est que cette totalité de l'arbre est résolu et chargés sur le chargement de la page. Je n'ai pas l'esprit que les per-sé, comme nous allons le lancer à travers l'optimiseur par la suite et jusqu'à la fin avec un gros fichier unique (réduction de RequireJS pour l'essentiel à une modularisation cadre). Cependant, je suis curieux de savoir si vous pouvez charger des trucs comme les vues et les modèles "à la demande".

Il y a le "simplifié CommonJS d'emballage", a expliqué ici, j'ai donc essayé ça:

define(function(require) {
  Backbone = require('Backbone');
  return Backbone.Router.extend({
    doStuff: function() {
      var MyView = require('js/myView');
      new MyView().render();
    }
  });
});

Cependant, en regardant Chrome réseau de l'inspecteur, il semble que RequireJS - de toute façon, même sans le déclenchement de la route qui déclenche la doStuff gestionnaire - encore des charges de l' myView de dépendance. Questions:

  • Est-ce réellement possible? Sont là, noir magicks dans RequireJS qui ressemble pour les appels à l' require() sans réellement le déclenchement de l' doStuff route?
  • Est-ce la théorie façon correcte de le faire "à la demande", le chargement paresseux de RequireJS des modules et des ressources?
  • La r.js optimiseur de toujours travailler comme annoncé si vous utilisez cette notation?

51voto

Simon Smith Points 5593

Est-ce réellement possible? Sont là, noir magicks dans RequireJS qui ressemble à des appels d'exiger() sans réellement le déclenchement de la doStuff route?

Lorsque vous utilisez le 'sucre' syntaxe il utilise Function.prototype.toString et une regex pour extraire vos références à require , puis la liste des dépendances avant d'exécuter la fonction. Fondamentalement, il devient le style normal de définir avec un tableau de deps comme premier argument.

De ce fait, il ne se soucie pas de l'endroit où votre besoin les appels sont et c'est pourquoi les instructions conditionnelles sont ignorés (il explique aussi pourquoi ceux - require appels d'utiliser une chaîne littérale, et pas une variable).

Est-ce la théorie façon correcte de le faire "à la demande", le chargement paresseux de RequireJS des modules et des ressources?

En utilisant le sucre, la syntaxe ne permet pas de conditionnel de chargement comme vous l'avez vu. La seule façon que je peux penser à du haut de ma tête est d'utiliser un require appel avec un tableau de deps et un rappel:

define(function(require) {
    var module1 = require('module1');

    // This will only load if the condition is true
    if (true) {
        require(['module2'], function(module2) {

        });
    }

    return {};
});

Seul inconvénient, c'est une autre fonction imbriquée, mais si vous êtes après de la performance, alors c'est un valide route.

La r.js optimiseur de toujours travailler comme annoncé si vous utilisez cette notation?

Si vous utilisez le 'sucre' la syntaxe, alors oui, l'optimiseur ne fonctionne correctement. Un exemple:

modules/test.js

define(function(require) {
    var $ = require('jquery');
    var _ = require('underscore');

    return {
        bla: true
    }
});

Une fois compilé par r.js cela ressemble à:

define('modules/test', ['require', 'jquery', 'underscore'], function(require) {
    var $ = require('jquery');
    var _ = require('underscore');

    return {
        bla: true
    }
});

En conclusion, vous pouvez charger des trucs sous certaines conditions, mais comme vous l'avez mentionné, si vous avez l'intention d'optimiser le projet avec r.js, il n'y a pas une surcharge énorme en utilisant simplement le sucre de la syntaxe.

3voto

Vous pouvez également vouloir vérifier nécessitent-paresseux.

Il a un temps d'exécution de la composante et un délai de fabrication de composants. Le composant d'exécution vous permet paresseusement besoin d'un module (note de l' lazy! plugin):

define(["lazy!mymodule"], function(mymodule) {
    ...
});

Dans le contexte précédent, mymodule est une promesse, la vraie module sera chargé avec get() et sera mis à disposition dans l' then() de rappel:

mymodule.get().then(function(m) {
    // here m is the real mymodule
});

Nécessitent-paresseux s'intègre avec r.js pour créer automatiquement des "paquets" de fichiers Javascript. Il gère également automatiquement les cache-busting pour les paquets. Il y a plusieurs exemples pour vous faire une idée. Il est également Grunt et Bower intégration.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X