2011-03-09 15 views
5

¿Alguien está familiarizado con Yabble u otros cargadores CommonJS del lado del navegador?Primeros pasos con Yabble - módulo CommonJS del lado del navegador cargando

Estoy experimentando con Node.js y me gustaría mucho crear módulos de Javascript que puedan usarse indistintamente en el lado del servidor y del lado del cliente. Esto puede terminar siendo más un tipo de cosas "porque es asombroso" que "porque es práctico y útil".

Como tal, básicamente intento que el método CommonJS require() funcione en el lado del navegador, que es exactamente lo que se supone que debe hacer Yabble. Aunque no sé por dónde empezar. No puedo encontrar ninguna documentación aparte de lo que se encuentra en Yabble's Github readme, y eso no ayuda mucho.

En esencia todo lo que he hecho es poner esto en una página HTML ...

<script src="yabble.js"></script> 

<!-- Uses require --> 
<script> 
    require.setModuleRoot('http://localhost:8030/') 
    my_module = require('my_module') 
</script> 

Pero en cualquier momento me llama a la función require() todo lo que consigo una excepción Synchronous require() is not supported. tirado.

¿Alguien me puede ayudar a empezar? ¿Dónde se supone que debo cargar yabble.js donde se supone que debo llamar? ¿Hay alguna forma especial de ejecutar mis módulos de Javascript?

Respuesta

6

Al cargar código Javascript que tendrá que utilizar la función require() en el navegador, el punto de entrada en ese código debe ser la función require.run().

por ejemplo, bueno:

<script src="yabble.js"></script> 

<script> 
    require.setModuleRoot('http://localhost:8030/') 
    require.run('my_module') // <-- Uses require() function somewhere 
</script> 

por ejemplo, Bad (obtendrá el error Synchronous require() is not supported):

<script src="yabble.js"></script> 
<script src="http://localhost:8030/my_module.js"></script> <!-- <== Use's require function somewhere --> 

FYI, es bastante ingenioso cómo Yabble hace esto. Analizará estáticamente su código fuente de JavaScript, creo que básicamente usará una expresión regular para buscar el método require(), y luego intentará extraer esa secuencia de comandos .js del servidor, luego realizará el mismo análisis estático de esa secuencia de comandos .js, y incesantemente.

Esto puede ser particularmente confuso porque realmente cargará esos scripts .js incluso si la lógica de control significara que el flujo del programa nunca llegaría a la función require(). por ejemplo, si usted tenía ...

if (False) { require('some_module'); } 

... Yabble hará aún carga de este módulo.

+0

¿Ejecuta el módulo en el caso 'if (falso) {require ('x;)}', o simplemente lo extrae del servidor? –

+0

@Kragen Realmente no estoy seguro, haré una prueba cuando tenga la oportunidad. –

+0

¡Genial! Tal vez lo intente yo mismo. –

2

La carga síncrona de módulos en el navegador es problemática. Una construcción como:

var x = require('something_remote.js') 

implica que el navegador va a detener su código (es decir bloque), ir a buscar el archivo remoto, analizarlo, y luego regresar a que las exportaciones. Pero esto no coincide con el entorno de navegador de subproceso único: estaríamos deteniendo el hilo principal de JavaScript (y, por lo tanto, la interactividad de la página para el usuario) en el rendimiento de la red. Así que los navegadores han evolucionado contra este escenario, para favorecer la carga asíncrona en su propio cronograma. Hay un poco de buena discusión aquí:

http://www.sitepen.com/blog/2010/07/16/asynchronous-commonjs-modules-for-the-browser-and-introducing-transporter/

Un patrón que podría trabajar aquí es que un require() aplicación no bloquear de forma sincrónica, obtiene el archivo a través de XHR y luego evals, pero que parece correr contra todos la compatibilidad/infraestructura del navegador para la carga asíncrona basada en archivos. También me interesan las implicaciones que tendría para la primitiva de dominio cruzado de la seguridad del navegador.

Así que con el fin de ajustar el modelo de carga del navegador asíncrono, tendremos que utilizar un mecanismo de devolución de llamada como:

require("something.js", function() { // called later, after something.js has loaded! }) 

Parece que RequireJS está haciendo esto:

http://requirejs.org/docs/start.html

Tal vez darle una oportunidad?

Entornos de JavaScript como NodeJS, etc., creados con la provisión de módulos "locales" de carga desde el disco, en lugar de hosts de red foránea, que pueden realizar la carga síncrona.

Les agradecería mucho las correcciones de expertos JS :-)

+0

¡Gracias por la información útil! De hecho, estaba buscando información más específica sobre Yabble, así que realmente no puedo marcar esto como la respuesta, pero eventualmente lo descubrí. –

+0

para el registro: yabble solo sincroniza ajax para requerir() en modo de desarrollo. si empaqueta todo en un archivo (con yabbler) ya tiene todos los módulos y una sincronización 'require()' está bien. – oberhamsi

Cuestiones relacionadas