Comment puis-je modifier l'ordre dans lequel Meteor charge des fichiers Javascript?

Lorsque vous faites un projet avec le cadre Meteor, il regroupe tous les fichiers ensemble, mais il ne semble pas y avoir de moyen de dire explicitement «Je souhaite que ce fichier soit chargé avant celui-ci».

Par exemple, j'ai 2 fichiers javascript: foo.js et bar.js

Le fichier bar.js contient en réalité un code qui dépend de celui de foo.js mais Meteor charge la bar.js avant que foo.js , ce qui brise le projet.

  • Dans node.js, j'utiliserais simplement require('./bar') intérieur de foo.js
  • Dans le navigateur , je mets une étiquette <script> pointant foo.js et une autre, après, en montrant bar.js , afin de charger les fichiers dans le bon ordre.

Comment pouvons-nous le faire dans Meteor ?

Selon la documentation Meteor, les fichiers sont actuellement chargés dans cette commande:

  1. Les fichiers dans [project_root] / lib sont chargés en premier
  2. Les fichiers sont triés par profondeur de répertoire. Les fichiers plus profonds sont chargés en premier.
  3. Les fichiers sont triés par ordre alphabétique.
  4. Les fichiers principaux * sont chargés en dernier.

Source: http://docs.meteor.com/#structuringyourapp

Pas une solution pour tous les scénarios, mais je pense que tout ce qui dépend d'un autre code serait placé dans une fonction Meteor.startup, pour s'assurer que tout est déjà chargé.

Vous pouvez toujours nous utiliser un chargeur JS comme yepnope.js et l'ajouter au fichier client.js. Cela fonctionne pour moi.

J'ai un ensemble de fonctions d'utilité que j'ai structurées sous l'espace de noms commun (js global).

C'est à dire

 // utils/utils.js Utils = {}; 

Puis dans les sous-dossiers:

 // utils/validation/validation.js Utils.Validation = {}; // utils/validation/creditCard.js Utils.Validation.creditCard = ... // validation logic etc 

J'ai aussi beaucoup de code qui utilise Utils et ses sous-objets.

De toute évidence, cette structure ne fonctionne pas comme des sous-dossiers de chargement de météoré en premier.

Pour le faire fonctionner comme prévu, j'ai dû créer / sous-dossier / sous-dossier / sous-dossier avec des noms sans signification, puis enfoncer l'objet racine dans le sous-dossier le plus profond et ramener les objets dans les sous-dossiers pas si profonds.

Il est extrêmement contre-intuitif pour le goût et l'erreur (supposons que vous avez un composant qui est encore plus profond dans la structure du dossier).

Pour résoudre ce problème, j'ai utilisé la bibliothèque Q avec des défers et des promesses. La solution n'est toujours pas propre, car elle vous permet de répéter et de vérifier des codes de routine, mais cela vous donne un contrôle total sur l'ordre de chargement sans déranger la structure du répertoire (salut aux personnes qui disent que vous pouvez organiser le code météorique comme vous le souhaitez).

Exemple:

 //utils.js UtilsDefer = UtilsDefer || Q.defer(); UtilsDefer.resolve({ // here some root utils stuff }); //cards.js // here we'll depend on Utils but don't want to care about directory structure UtilsDefer = UtilsDefer || Q.defer(); // it will be a) already // resolved defer from utils.js, or b) new defer that will // be resolved later in utils.js UtilsDefer.then(function(Utils) { // do something with utils usage, or for instance add some fields here Utils.CreditCardDefer = Utils.CreditCardDefer || Q.defer(); Utils.CreditCardDefer.resolve({ // Credit card utils here }) }); //someOtherFile.js // it will be pain to use sub-objects with this method though: UtilsDefer = UtilsDefer || Q.defer(); UtilsDefer.then(function(Utils) { Utils.CreditCardDefer = Utils.CreditCardDefer || Q.defer(); Utils.CreditCardDefer.then(function(CreditCard) { // do stuff with CreditCard _if_ you need to do it on startup stage }) }); 

Ceci est l'exemple d'un cas d'utilisation plutôt étroit, car vous serez surtout heureux de gérer ces globals à l'intérieur de certains rappels d'interaction utilisateur ou Meteor.startup où tout est déjà initialisé. Sinon, si vous voulez un contrôle fin sur l'ordre d'initialisation sur un stade très précoce, cela pourrait être une solution.