web-dev-qa-db-fra.com

RequireJS: existe-t-il un moyen d'obtenir plusieurs URL de base?

Je souhaite utiliser un domaine séparé comme cadre JavaScript et cela créera une configuration de base requise que je peux augmenter à partir de l'application.

foo.example.com
    main.js
    lib/foo-specific.js
framework.example.com
    framework.js <-- entry point
    lib/jquery.js
    lib/etc...

De manière optimale, j'aimerais pouvoir exiger 'lib/foo-specific' et/ou 'lib/jquery' et que les chemins se résolvent correctement, mais d'après ce que j'ai trouvé, il n'y a aucun moyen de le faire, à moins que J'utilise une clé/valeur de chemin spécifique pour chaque fichier js dans le framework. Pour le moment, j'ai un plugin personnalisé pour charger le chemin donné avec une URL de base différente (par exemple fw!lib/jquery), mais si je voulais utiliser le text! plugin, cela ne fonctionnera pas car le chaînage de plugin n'est pas pris en charge.

Voir https://github.com/jpillora/js-framework pour ce que j'ai actuellement, et aussi https://github.com/jpillora/prettyprinter pour un cas d'utilisation.

Existe-t-il un moyen propre de résoudre ce problème? ou pour atteindre plusieurs URL de base?

Remarque: j'ai également examiné plusieurs instances de demande, bien que je ne pense pas que cela fonctionnerait car j'aimerais que l'application puisse accéder à la configuration du framework.

36
jpillora

Réponse de James Burke sur la page RequireJS Github Issue: Issue # 447: Multiple Base URLs · jrburke/requirejs .

Cela s'avère assez simple si data-main est le seul point d'entrée de vos scripts (commentaires pour plus d'informations) , j'ai résolu mon problème particulier avec le Suivant:

Mon application index.html:

<script src="http://framework.jpillora.com/js/lib/require.js" 
  data-main="http://framework.jpillora.com/js/framework" > </script>

a le point d'entrée requirejs défini sur framework.js:

var framework = ... //set using script elements src attribute

require.config({

    baseUrl: 'js/',

    //Framework paths
    paths: {
      'framework': framework,
      'lib'      : framework + 'js/lib',
      'ext'      : framework + 'js/ext',
      'util'     : framework + 'js/util'
    },

    //Shortcuts
    map: {
      '*': {
        ...
      }
    },

    //Non-modularised libraries with deps
    shim: {
      ...
    }
});

require(['main']);

Donc, au lieu de faire normalement index.html->main.js, Nous ajoutons une étape supplémentaire index.html->framework.js->main.js, Qui donne au code de l'application la connaissance des chemins vers le code du framework.

Par exemple, dans l'application http://prettyprint.jpillora.com/ , une fois que require a chargé framework.js, Il installera les chemins vers lib/... Auxquels - http://framework.jpillora.com/ et définissez baseUrl comme ./js/ donc une fois que main est requis, l'URL de base sera définie sur c'est son propre domaine et lib pointant vers un autre domaine.

Ce qui entraîne la résolution de require(['lib/foo', 'view/bar']); en:

http://framework.jpillora.com/js/lib/foo.js Et http://prettyprint.jpillora.com/js/view/bar.js

Comme affiché ici, l'application n'est qu'un main.js Tout le reste provient du framework:

chrome devtools loaded app

Donc finalement, chaque fois que je charge main.js Via une application avec le framework.js Ci-dessus, j'ai alors accès à toutes mes bibliothèques et classes utilitaires couramment utilisées. Voir la source de l'application.

Notez également qu'avec l'optimiseur r.js Et une structure de fichiers locaux Nice, on peut également optimiser l'application en un seul fichier js en tirant uniquement ce qui est requis de framework.

35
jpillora

Le problème

J'ai eu un problème similaire en essayant de mettre en place un environnement de test. J'avais une structure de fichiers comme celle-ci:

myApp/
    src/
        js/
            app.js
            data.js
            lib/underscore.js
    test/
        karma.conf.js
        test-main.js
        matchers.js
        spec/
            data.js

Voici où ça devient compliqué: mes scripts d'application (app.js et data.js) supposons une configuration RequireJS qui résout data en src/js/data.js, lib/underscore à src/js/lib/underscore.js etc, j'ai donc également besoin de cette configuration dans mon environnement de test:

test/test-main.js
-----------------
require.config({
  // Karma serves files under /base, which is the basePath from your config file
  baseUrl: '/base/src/js',
  // ...
});

Maintenant, je peux écrire mes tests:

test/spec/data.js
-----------------
define(['data', '../../test/matchers'], function(dataModule) {
    describe('The data module', function() {
        it('should satisfy my custom matcher', function() {
            expect(dataModule).toSatisfyMyCustomMatcher();
        });
    });
});

Avec quelques matchers personnalisés:

test/matchers.js
----------------
define([], function() {
    beforeEach(function() {
        this.addMatchers({
            toSatisfyMyCustomMatcher: function() {
                return this.actual.isGood;
            },
        });
    });
});

Cependant, que '../../test/matchers' la partie est horriblement laide. Les spécifications de test ne devraient pas être dérangées par la connaissance des chemins de fichiers vers d'autres modules - c'est le travail de RequireJS. Au lieu de cela, nous voulons utiliser des noms symboliques.

La solution

Le RequireJS path config peut également mapper des répertoires.

Le chemin utilisé pour un nom de module ne doit pas inclure d'extension, car le mappage de chemin peut être pour un répertoire.

Donc, la solution est une configuration de chemin simple:

test/test-main.js
-----------------
require.config({
  baseUrl: '/base/src/js',
  paths: {
      test: '../../test',
  },
  // ...
});

Je peux maintenant me référer au répertoire test comme s'il s'agissait d'un enfant du baseUrl:

test/spec/data.js
-----------------
define(['data', 'test/matchers'], function(dataModule) {
    // ...
});

Ce qui dans mon cas revient à peu près de la même manière que si je pouvais avoir plusieurs baseUrls.

10
Emil Lundberg

requiert le multiversion

Essaye ça

context: Un nom à donner à un contexte de chargement. Cela permet à require.js de charger plusieurs versions de modules dans une page, tant que chaque appel de niveau supérieur require spécifie une chaîne de contexte unique. Pour l'utiliser correctement, consultez la section Prise en charge du multiversion.

Regardez comment nous avons géré le routage et le contexte dans BoilerplateJS qui est une architecture de référence pour le développement de produits à grande échelle. Nous avons utilisé la bibliothèque crossroads.js pour router les modules et les composants de l'interface utilisateur. Tout ce qu'il y a à faire est d'ajouter le chemin/hachage à l'ensemble des routes et il sera acheminé à travers le framework.

En tant que exemple , tous les chemins des composants de l'interface utilisateur sont ajoutés à l'objet contrôleur d'URL.

En ce qui concerne l'accès aux informations de configuration du framework dans toute l'application, les configurations/paramètres peuvent être attachés à l'objet de contexte global qui est accessible dans l'application.

0
Himeshi