2012-02-09 10 views
5

Im empezando a tipo de envolver mi cabeza alrededor RequireJS y la nueva estructura Dojo AMD, pero tienen un problema con algunas de las primeras pruebas:¿Por qué la sintaxis del Contenedor JJ Simplificado no funciona en mi módulo Dojo AMD?

CG/signup.js:

define(['dojo/_base/fx', 'dojo/dom'], function(fx, dom){  
    return function(){ 
     this.hidePreloader = function(id){ 
      var preloader = dom.byId(id); 
      fx.fadeOut({node : preloader}).play() 
     } 
    } 
}) 

Esto funciona bien. En el archivo maestro cg.js:

require(['dojo/_base/kernel', 'dojo/_base/loader']) 
dojo.registerModulePath('cg', '../cg') 

require(['cg/signup', 'dojo/domReady!'], function(Signup){ 
     var sp = new Signup(); 
     sp.hidePreloader('preloader') 
}) 

Bam. Hecho. Sin embargo, al usar la estructura simplificada CommonJS Wrapper:

define(function(require){  
    var fx = require('dojo/_base/fx'), 
     dom = require('dojo/dom'); 

    return function(){ 
     this.hidePreloader = function(id){ 
      var preloader = dom.byId(id); 
      fx.fadeOut({node : preloader}).play() 
     } 
    } 
}) 

Me sale un error undefinedModule. Parece provenir de la línea dojo/_base/fx, pero no sé por qué.

ACTUALIZACIÓN

Para mayor claridad.

guiones index.html

<script type="text/javascript" src="js/dojo/dojo.js.uncompressed.js" data-dojo-config="isDebug:true,async:true"></script> 
<script type="text/javascript" src="js/cg.js"></script> 

cg.js

require(['dojo/_base/kernel', 'dojo/_base/loader']) 
dojo.registerModulePath('cg', '../cg') 

require(['cg/signup', 'dojo/domReady!'], function(signup){ 
    signup.testFunc() 
}) 

js/CG/signup.js

define(['require', 'exports'], function(require, exports){ 
    var dom = require('dojo/_base/kernel'); 
// Any other require() declarations (with very very few exceptions like 'dojo/_base/array throw undefinedModule errors!!! 

    // without any error causing requires, this works fine. 
    exports.testFunc = function(){ 
     alert("hello") 
    } 
}) 
+0

Hmm, una variación ligeramente diferente parece funcionar en jsFiddle. (Pero no puedo vincularlo ahora ya que JSFiddle está en modo de solo lectura.) ¿Podría dar más detalles sobre el error exacto? – Domenic

+0

Ese es el error exacto. Al usar la técnica de contenedor simplificado CommonJS con las mismas rutas y las mismas instrucciones requeridas, la consola imprime un error 'undefinedModule'. Tengo 'isDebug = true' en la configuración del script y' debugAtAllCosts' no arroja nada más. ¿Cuál es la variación que funciona para usted? – Phix

+0

No puedo separarme en varios archivos en JSFiddle, así que probé 'define (" foo ", function (require) {...})' donde '' 'contiene sus instrucciones requeridas, más' console.log' s para los objetos 'fx' y' dom'. Dos objetos de aspecto loco se registraron en la consola ... ¿Dojo 1.7.1? – Domenic

Respuesta

3

dojo es completamente compatible con el formato simplificado CommonJS Wrapper. sin embargo, hay una condición previa ... no debe tener una matriz de dependencias.

define(function (require, exports, module) { 
    var fx = require('dojo/_base/fx'), 
     dom = require('dojo/dom'); 

    // continue... 
}); 

esto no funcionará el mismo

define(['require', 'exports', 'module'], function (require, exports, module) { 
    var fx = require('dojo/_base/fx'), 
     dom = require('dojo/dom'); 

    // continue... 
}); 

ni esto ...

// in this case require, exports and module will not even exist 
define([], function (require, exports, module) { 
     var fx = require('dojo/_base/fx'), 
     dom = require('dojo/dom'); 

    // continue... 
}); 
+0

Gracias por agregar esta conversación, tendré que volver a abrir ese proyecto y hacer más pruebas. Es una advertencia interesante, ¿sabes más acerca de por qué? – Phix

+1

se hace de esta manera porque para admitir este formato, el cuerpo de la función necesita ser escaneado para el uso (s) de 'require (...)' y eso agrega un poco de sobrecarga. para evitar esa sobrecarga donde no se necesita, necesita "señalizar" al cargador que usted es (o no depende de su perspectiva) usando este formato. la "señal" de que está utilizando este formato es no tener una matriz de dependencias, por lo que una matriz de dependencias vacía es diferente de no tener ninguna. – neonstalwart

+0

Probé este sencillo ejemplo en dojo 1.8.3 y no funcionó en absoluto. –

1

es require definido? No veo de dónde vendría ese argumento. Creo que es posible que tenga que hacer algo como

define(["require"], function(require){ ... 
+0

No, funciona con 'dojo/_base/kernel' pero no' dojo/_base/fx', así que require está definido. – Phix

1

Empecé a pensar que tal vez no estaba destinado a aprender Dojo. Pero, todo se combina con un poco más de lectura. No estoy seguro de lo que hice diferente o lo que sea, pero aquí está el diseño de trabajo.

guiones index.html y config

<script type="text/javascript"> 
dojoConfig = { 
    async : true, 
    isDebug : true, 
    debugAtAllCosts : true, 
    packages : [{ 
     name : 'cg', 
     location : '/../js/cg' 
    }] 
} 
</script> 
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js"></script> 
<script type="text/javascript" src="js/cg.js"></script> 

js/cg.js

require(['cg/signup', 'dojo/ready'], function(signup){ 
    signup.init('preloader') 
}) 

JS/CG/signup.js

define(['dojo', 'require'], function(dojo, require){ 
    var fx = require('dojo/_base/fx') 

    return new function(){  
     this.init = function(id){ 
      fx.fadeOut({node : dojo.byId(id)}).play() 
     } 
    } 
}) 

Again , n No estoy del todo seguro de por qué la declaración var fx = require(...) funciona de manera diferente en este que los otros, podría ser la versión que descargué vs. CDN, a quién le importa. Funciona.Algunos enlaces que he utilizado para ayudar a los demás, posiblemente en el mismo barco:

Writing Modular JS

AMD vs CommonJS Wrapper

Dojo Toolkit AMD

Dojo Config (1.7)

2

Aquí hay un pequeño envoltorio sobre Dojo definir que utiliza código tomado de RequireJS para calcular las dependencias basadas en el toString de la función de definición. Envuelve la "definición" actual en el espacio de nombres global, calcula las dependencias y luego llama a la definición envuelta.

defineWrapper.js:

// Workaround for the fact that Dojo AMD does not support the Simplified CommonJS Wrapper module definition 
(function() { 
    var commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, 
     cjsRequireRegExp = /require\(\s*["']([^'"\s]+)["']\s*\)/g, 
     ostring = Object.prototype.toString; 
    function isArray(it) { 
     return ostring.call(it) === '[object Array]'; 
    } 
    function isFunction(it) { 
     return ostring.call(it) === '[object Function]'; 
    } 
    var oldDefine = define; 

    define = function(name, deps, callback) { 
     //Allow for anonymous functions 
     if (typeof name !== 'string') { 
      //Adjust args appropriately 
      callback = deps; 
      deps = name; 
      name = null; 
     } 

     //This module may not have dependencies 
     if (!isArray(deps)) { 
      callback = deps; 
      deps = []; 
     } 

     //If no name, and callback is a function, then figure out if it a 
     //CommonJS thing with dependencies. 
     if (!deps.length && isFunction(callback)) { 
      //Remove comments from the callback string, 
      //look for require calls, and pull them into the dependencies, 
      //but only if there are function args. 
      if (callback.length) { 
       callback 
        .toString() 
        .replace(commentRegExp, '') 
        .replace(cjsRequireRegExp, function(match, dep) { 
         deps.push(dep); 
        }); 

       //May be a CommonJS thing even without require calls, but still 
       //could use exports, and module. Avoid doing exports and module 
       //work though if it just needs require. 
       //REQUIRES the function to expect the CommonJS variables in the 
       //order listed below. 
       deps = (callback.length === 1 ? ['require'] : 
        ['require', 'exports', 'module']).concat(deps); 
      } 
     } 

     if(name === null) { 
      return oldDefine(deps, callback); 
     } else { 
      return oldDefine(name, deps, callback); 
     } 
    } 
})(); 

¿Cómo se utiliza?

<script src="...dojo..."></script> 
<script src="defineWrapper.js"></script> 
<script>require(["some_simplified_commonjs_defined_module"], function(module) { 
    // use module here 
});</script> 
2

Tenga en cuenta que Dojo no es compatible con el estilo CommonJS simplificado para la detección de la dependencia cuando se hace una acumulación . Esto significa que deberá usar el estilo de lista de dependencia normal o tendrá que duplicar todas sus dependencias al definir capas en el perfil de compilación.

Aquí está el fallo correspondiente en su programa de seguimiento:

http://bugs.dojotoolkit.org/ticket/15350

+0

a partir de dojo 1.9.0 esto ahora es compatible con la compilación – neonstalwart

Cuestiones relacionadas