Динамическое требование в RequireJS, получение ошибки" имя модуля еще не загружено для контекста"?



есть ли способ определить модуль, который "динамически" загружает другие модули в RequireJS? Если да, то как оптимизатор (r.js) понимает, как/когда модуль должен быть включен?



например,dynModules модуль, который определяет пары имя/путь:



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


другой модуль будет загружать модули динамически, на основе массива. Это будет не работает:



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

// ...
});


... дает мне:




Непойманные Ошибка: Модуль наименование "модуль" еще не загружены
контекст._ : Использовать требуется([])
http://requirejs.org/docs/errors.html#notloaded




Я могу решить ошибку, но это уже не" динамический":



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

// ...
});
636   2  

2 ответов:

ограничение относится к упрощенному синтаксису CommonJS по сравнению с обычным синтаксисом обратного вызова:

загрузка модуля по своей сути является асинхронным процессом из-за неизвестного времени его загрузки. Однако, RequireJS в эмуляция спецификации CommonJS на стороне сервера пытается дать вам упрощенный синтаксис. Когда вы делаете что-то вроде этого:

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

то, что происходит за кулисами, заключается в том, что RequireJS смотрит на тело вашего кода функции и анализирует, что вам нужно " foo " и загружает его до выполнения функции. Однако, когда переменная или что-то другое, чем простая строка, например, ваш пример...

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

...затем Require не может разобрать это и автоматически конвертировать его. Решение заключается в преобразовании синтаксиса обратного вызова;

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

учитывая вышесказанное, вот один из возможных вариантов переписывания вашего 2-го примера для использования стандартного синтаксиса:

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: из вашего собственного ответа я вижу, что вы используете подчеркивание/lodash, поэтому используйте _.values и _.object можно упростить цикл через массив аргументов, как указано выше.

отвечая самому себе. С сайта RequireJS:

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

это не удается, потому что requirejs должен быть уверен, чтобы загрузить и выполнить все зависимости перед вызовом функции фабрики выше. [...] Итак, либо не передавайте массив зависимостей, либо, если вы используете массив зависимостей, перечислите все зависимости в нем.

мое решение:

// 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'
    };
});

загрузчика:

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

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

        // Use deps...
    });
});

Comments

    Ничего не найдено.