Dynamiczne Wymaganie w RequireJS, uzyskanie błędu "Nazwa modułu nie została jeszcze załadowana dla kontekstu"?

Czy istnieje sposób na zdefiniowanie modułu, który "dynamicznie" ładuje inne moduły w RequireJS? Jeśli tak, to w jaki sposób optymalizator (r.js) rozumie, w jaki sposób/kiedy moduł musi być dołączony?

Na przykład niech dynModules moduł definiujący pary nazwa / Ścieżka:

define([], function () {
    return ['moduleA', 'moduleB']; // Array of module names
});

Inny moduł będzie dynamicznie ładował Moduły, bazując na tablicy. To nie zadziała :

define(['dyn_modules'], function (dynModules) {
    for(name in dynModules) {   
        var module = require(path); // Call RequireJS require
    }

    // ...
});

... daje:

Uncaught Error: Nazwa modułu "moduleA" nie została jeszcze załadowana dla kontekst:_. Użyj wymagaj([]) http://requirejs.org/docs/errors.html#notloaded

Mogę rozwiązać błąd , ale to już nie jest "dynamiczne":

define(['dyn_modules', 'moduleA', 'moduleB'], function (dynModules) {
    for(name in dynModules) {   
        var module = require(path); // Call RequireJS require
    }

    // ...
});
Author: gremo, 2013-07-03

2 answers

Ograniczenie odnosi się do uproszczonej składni CommonJS vs. normalnej składni wywołania zwrotnego:

Ładowanie modułu jest z natury procesem asynchronicznym z powodu nieznanego czasu jego pobierania. Jednak Wymagajjs w emulacji po stronie serwera CommonJS spec stara się podać uproszczoną składnię. Kiedy robisz coś takiego:

var foomodule = require('foo');
// do something with fooModule

To, co dzieje się za kulisami, to to, że RequireJS patrzy na treść kodu funkcji i analizuje, że potrzebujesz " foo " i ładuje go przed wykonaniem funkcji. Jednak, gdy zmienna lub cokolwiek innego niż prosty ciąg znaków, takich jak twój przykład...

var module = require(path); // Call RequireJS require

...następnie Require nie jest w stanie tego przetworzyć i automatycznie przekonwertować. Rozwiązaniem jest konwersja na składnia wywołania zwrotnego;

var moduleName = 'foo';
require([moduleName], function(fooModule){
    // do something with fooModule
})

Biorąc pod uwagę powyższe, oto jeden z możliwych przepisań twojego drugiego przykładu użycia standardowej składni:

define(['dyn_modules'], function (dynModules) {
    require(dynModules, function(){
        // use arguments since you don't know how many modules you're getting in the callback
        for (var i = 0; i < arguments.length; i++){
            var mymodule = arguments[i];
            // do something with mymodule...
        }
    });

});

EDIT: z twojej własnej odpowiedzi widzę, że używasz podkreślenia / lodash, więc użycie _.values i _.object może uprościć zapętlanie tablicy argumentów jak powyżej.

 65
Author: explunit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-03 13:37:45

Odpowiadam przed sobą. Ze strony Wymagajs:

//THIS WILL FAIL
define(['require'], function (require) {
    var namedModule = require('name');
});

To się nie powiedzie, ponieważ requirejs musi upewnić się, że załaduje i wykona wszystkie zależności przed wywołaniem powyższej funkcji factory. [...] Tak więc albo nie przekazuj tablicy zależności, albo jeśli używasz tablicy zależności, wymień w niej wszystkie zależności.

Moje rozwiązanie:

// Modules configuration (modules that will be used as Jade helpers)
define(function () {
    return {
        'moment':   'path/to/moment',
        'filesize': 'path/to/filesize',
        '_':        'path/to/lodash',
        '_s':       'path/to/underscore.string'
    };
});

The loader:

define(['jade', 'lodash', 'config'], function (Jade, _, Config) {
    var deps;

    // Dynamic require
    require(_.values(Config), function () {
        deps = _.object(_.keys(Config), arguments);

        // Use deps...
    });
});
 7
Author: gremo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-03 13:27:27