javascript browser module requirejs r.js

javascript - Dynamic require en RequireJS, obteniendo el error "El nombre del módulo no se ha cargado todavía para el contexto"?



browser module (2)

La limitación se relaciona con la sintaxis CommonJS simplificada vs. la sintaxis de devolución de llamada normal:

Cargar un módulo es intrínsecamente un proceso asíncrono debido a la sincronización desconocida de la descarga. Sin embargo, RequireJS en la emulación de la especificación CommonJS del lado del servidor intenta darle una sintaxis simplificada. Cuando haces algo como esto:

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

Lo que sucede detrás de escena es que RequireJS está mirando el cuerpo de su código de función y analizando que necesita ''foo'' y lo carga antes de la ejecución de su función. Sin embargo, cuando una variable o cualquier cosa que no sea una cadena simple, como su ejemplo ...

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

... luego Require no puede analizar esto y convertirlo automáticamente. La solución es convertir a la sintaxis de devolución de llamada;

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

Dado lo anterior, aquí hay una posible reescritura de su segundo ejemplo para usar la sintaxis estándar:

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... } }); });

EDITAR: A partir de su propia respuesta, veo que está utilizando subrayado / lodash, por lo que el uso de _.values y _.object puede simplificar el bucle a través de la matriz de argumentos como se _.object anteriormente.

¿Hay alguna manera de definir un módulo que cargue "dinámicamente" otros módulos en RequireJS? En caso afirmativo, ¿cómo entiende el optimizador (r.js) cómo / cuándo se debe incluir un módulo?

Por ejemplo, deje dynModules un módulo que define pares nombre / ruta:

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

Otro módulo va a cargar módulos de forma dinámica, en función de la matriz. Esto no funcionará :

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

... me da:

Error no detectado: el nombre del módulo "moduleA" no se ha cargado aún para el contexto: _. Use require ([]) http://requirejs.org/docs/errors.html#notloaded

Puedo resolver el error , pero ya no es "dinámico":

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


Respondiendo a mí mismo. Desde el sitio web RequireJS:

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

Esto falla porque requirejs necesita asegurarse de cargar y ejecutar todas las dependencias antes de llamar a la función de fábrica anterior. [...] Entonces, o bien no pase la matriz de dependencia, o si usa la matriz de dependencia, enumere todas las dependencias en ella.

Mi solución:

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

El cargador:

define([''jade'', ''lodash'', ''config''], function (Jade, _, Config) { var deps; // Dynamic require require(_.values(Config), function () { deps = _.object(_.keys(Config), arguments); // Use deps... }); });