web-dev-qa-db-fra.com

Chemins relatifs RequireJS

Je suis nouveau sur RequireJS. J'écris un certain nombre de liaisons personnalisées dans Knockout.js et je souhaite les diviser en utilisant des modules.

La disposition de mon code en ce moment est:

/
  default.html
  js
    code.js
    require-config.js 
    lib
      /require.js
      bridge
        bridge.js
        bindings1.js
        bindings2.js
        bindings3.js

Je veux charger bridge.js à partir de default.html et avoir cette charge dans tous les fichiers de liaisons. J'ai essayé de charger bridge.js en utilisant a ou en ligne js en utilisant la fonction require.

Ma configuration requise est très simple:

require.config({
    baseUrl: '/'
});

Dans bridge.js, j'ai des problèmes pour charger les fichiers en utilisant un chemin relatif. J'ai essayé:

require(['./bindings1', './bindings2', './bindings3'], function () {
    console.log('loaded');
});

Mais cela finit simplement par utiliser le chemin baseUrl + 'bindings1.js', par exemple. J'ai essayé différentes itérations dans bridge.js. Le seul succès que j'ai eu, c'est si j'écris tout le chemin:

require(['js/bridge/bindings1', 'js/bridge/bindings2', 'js/bridge/bindings3'], function () {
    console.log('loaded');
});

Mais ce n'est pas ce que je veux. Cela semble être un cas d'utilisation assez basique et je pense que je peux mal comprendre le fonctionnement des chemins relatifs.

Merci

31
Szymon Rozga

Les ID relatifs sont résolus par rapport à l'ID de module dans lequel l'ID est résolu. Voir la section module id format De spécification AMD .

Il existe deux façons de cadrer un ID de dépendance relative dans un contexte/portée correct:

Définir l'appel

Définir l'appel est le début/la définition du "module". Toutes les dépendances demandées dans l'appel define() sont étendues pour être dans/par rapport à l'ID de ce module. Exemple:

// does not matter what the file name is.
define(
    'hand/named/module'
    , ['./child']
    , factoryFunction
)

ou

// inside of 'hand/named/module.js' file.
define(
    ['./child']
    , factoryFunction
)

Dans les deux cas ci-dessus, ./child Est résolu par rapport à l'ID de module défini par l'appel define(). L'identifiant du module dans les deux cas est hand/named/module Et le ./child Est résolu en hand/named/child (+ '.Js' évidemment, quand le moment sera venu de l'obtenir)

"Portée" nécessite

Vous pouvez modifier la portée de l'appel require de global à local en le remplaçant. En fait, vous n'avez pas besoin de remplacer/conserver le nom require, c'est la signification de ce qu'il change. La fonctionnalité requise devient "locale" pour un module particulier.

// inside 'hand/named/module.js' file
define(
    ['require']
    , function(myLocalRequire){
        require('./child', function(){
            // outcome A
        })
        myLocalRequire('./child', function(){
            // outcome B
        })
    }
)

Là, dans le résultat A, vous continuez à utiliser "global" require - celui attaché à la portée parent. Votre ./child Se résout en baseURL + '/ enfant'

Le résultat B est de portée locale, lié à l'ID de module hand/named/module Donc, ./child Est résolu en hand/named/child

Ce que @CristiPufu a recommandé est de remplacer la variable globale require par un objet local qui sera local uniquement pour l'étendue de cette fonction:

// inside 'hand/named/module.js' file
define(
    ['require']
    , function(require){
        return function(){
            // here we have access only to "local" require,
            // since in the function declaration you decided to
            // override the 'require' variable with new object.
            // All code outside of this function will use global require.
            require('./child', function(){
                // outcome B
            })
        }
    }
)

Ma préférence est de mettre toutes les ressources relatives dans l'appel define. Les rend explicites et meeningfull car il est clair à quoi ils sont relatifs.

28
ddotsenko

Utilisez "packages" dans require config. Voici la réponse valable pour votre question sujet

require.config({
packages: [
{ 
    name: 'packagename',
    location: 'path/to/your/package/root',  // default 'packagename'
    main: 'scriptfileToLoad'                // default 'main' 
}]
   ... some other stuff ...
});

À l'intérieur du package, vous pourrez utiliser des chemins relatifs.

26
Dmitry Masley