javascript - ¿Cómo puedo cargar mi propio módulo js con goog.provide y goog.require?
dojo google-closure (7)
¡¡¡Actualizar!!!
La nueva versión de calcdeps.py cambia un poco el juego. Para crear tus deps.js ahora necesitas usar la marca -d. p.ej:
python path-to-closure-library/closure/bin/calcdeps.py -i path-to-your-src/requirements.js -o deps -d path-to-closure-library/closure/ -p path-to-your-src/ --output_file=path-to-your-src/deps.js
Compilar:
python path-to-closure-library/closure/bin/calcdeps.py -i path-to-your-src/requirements.js -d path-to-closure-library/closure/ -p ./ --output_file=path-to-your-release/scripts.min.js -c path-to-compiler/compiler.jar -f "--compilation_level=ADVANCED_OPTIMIZATIONS" -f "--debug=true" -f "--process_closure_primitives=true" -f "--manage_closure_dependencies=true" -o compiled
Entonces, el proceso es ahora mucho más fácil, pero tienes que usar tus poderes de ESP para descubrirlo como si estuviera totalmente indocumentado. El calcdeps.py ahora tampoco funciona con Python 3.1 en Windows, por lo que también es un montón de diversión. Algunos trucos lo hicieron funcionar para mí (lo cual no pondré aquí porque no soy un programador de Python y debe haber mejores maneras de hacerlo).
En general, el último día ha sido súper divertido, espero que esta publicación ayude a alguien a evitar el mismo disfrute.
Guido
Estamos tratando de cambiar el paquete de nuestro proyecto del dojo al cierre de google, pero hasta ahora no hemos tenido suerte. Aquí hay un ejemplo simple que ilustra lo que estamos tratando de lograr:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="runtime/src/core/lib/goog-rev26/base.js"></script>
<script>
goog.require("foo.bar");
function main() {foo.bar.echo("hello world")}
</script>
</head>
<body onload="main()">
</body>
</html>
Luego en /foo/bar.js
tengo:
goog.provide("foo.bar");
foo.bar.echo = function(s) {console.debug(s);}
Los errores que recibo en firebug son los siguientes:
goog.require could not find: foo.bar foo is not defined
Cuando busco en la pestaña Red, no hay una solicitud http para recuperar un archivo. Esperaba que la biblioteca de cierre generara una etiqueta de script para obtener bar.js
¡ayuda! ;)
De cualquier manera para que los módulos personalizados funcionen, al menos para la versión de desarrollo, es incluir manualmente los archivos js en la sección principal de la página html, después de la inclusión del archivo base.js de Google.
<script type="text/javascript" src="js/closure/goog/base.js"></script>
<script type="text/javascript" src="js/closure/custom/custom.js"></script>
<script type="text/javascript" src="js/closure/custom/sub/sub.js"></script>
...
Pero, debes preocuparte por la secuencia de inclusión por ti mismo. Para conjuntos de archivos personalizados no muy grandes funciona bien. Para la versión de producción, aún es mejor utilizar la compilación js source para obtener todos los beneficios de la biblioteca de cierre.
Este es un pequeño proyecto en el que he estado trabajando y que podría ser útil para usted: http://github.com/fintler/lanyard
Eche un vistazo al build.xml, al archivo llamado lanyard.js, y a todos los archivos ubicados en src / geom / *.
El build.xml tiene un ejemplo de cómo llamar a calcdeps.py a través de ant para todos los js ubicados en src. Puede que no sea la mejor manera de hacer las cosas, pero hasta ahora me ha funcionado.
Lo descubrí y no es muy difícil, pero hay algunos errores.
Básicamente, puede usar el script de generación de dependencias calcdeps.py ( debe leer los documentos de calcdeps.py ) en uno de los varios modos:
- Generando archivo deps.js
- Concatenando todo en un solo archivo, compilándolo opcionalmente usando el compilador de cierre.
Para el desarrollo, debe usar (1), ya que le permite no ejecutar calcdeps.py después de editar las fuentes JS, a menos que realice cambios en el árbol de dependencias. El resto de la respuesta es de esta manera, no he probado la otra todavía.
Esto es lo que hice para generarlo:
#!/bin/bash
cd closure-library/closure/goog
python ../bin/calcdeps.py -p ../../../js -o deps > ../../../my-deps.js
... asumiendo la siguiente estructura de directorios:
project/
closure-library/ (as checked out from SVN)
js/ (my JS code)
app.html
(El parámetro -p
atraviesa todos los archivos js en el directorio especificado y los documentos dicen que puede especificar varios directorios para buscar si es necesario).
La llamada anterior crea un archivo my-deps.js junto al app.html principal, que uso para ejecutar la aplicación. El archivo creado contiene información sobre mis archivos JS en js/
y se ve así:
goog.addDependency(''../../../js/controllers.js'', [''proj.controllers''], []);
goog.addDependency(''../../../js/ui.js'', [''proj.ui''], [''proj.controllers'']);
- donde la primera cadena es la ruta a mi archivo JS en relación a closing-library / closing / goog / base.js (¡esto es importante!), la segunda matriz es la lista de cadenas goog.provide
-d, y la última matriz es la lista de goog.require
-d cadenas.
Ahora en app.html tengo:
<script src="closure-library/closure/goog/base.js"></script>
<script src="my-deps.js"></script>
<script>
goog.require("proj.ui");
</script>
<script>
// here we can use the required objects
</script>
Nota:
- Además de incluir el archivo base.js del cierre, incluyo mis deps.js generados
- Como se mencionó en el tutorial, la llamada
goog.require
debe estar en una etiqueta de secuencia de comandos separada , ya que agrega una etiqueta de secuencia de comandos para cargar las secuencias de comandos necesarias y se cargan después de que la etiqueta de secuencia de comandos actual haya finalizado su procesamiento.
Gotchas:
- El problema descrito anteriormente con rutas que son relativas a base.js.
goog.require
crea la URL del script para cargar concatenando la URL base de base.js (es decir, sin el nombre de la hoja base.js) y el primer parámetro de goog.addDependency en deps.js. - calcdeps.py no funciona bien en Windows, en particular utilizando las barras invertidas en los literales de cadena deps.js
- Si algo no funciona bien, es posible que desee revisar todos los problemas que mencionan calcdeps y asegurarse de tener una verificación actualizada.
Pude hacerlo funcionar agregando lo siguiente a deps.js
:
goog.addDependency(''../../../foo/bar.js'', [''foo.bar''], []);
Firefox ahora realiza una solicitud http a /foo/bar.js
cuando encuentra la declaración goog.requires
.
Sin embargo, el archivo contiene este comentario:
// This file has been auto-generated by GenJsDeps, please do not edit.
De acuerdo con this , GenJsDeps
es lo mismo que calcdeps.py
. Si observa la documentación, parece que hay un -o deps
que volverá a generar deps.js
para que no se deps.js
manualmente.
Sí, debes usar calcdepds.py. Creé una gran publicación en el blog después de muchas pruebas y errores para descubrir la mejor manera de hacerlo, también repaso las diferencias entre dojo.require y goog.require:
solución:
Descargue el cierre a sus proyectos externos (o activos, lo que sea).
no se moleste en configurar onload, delay, jugar con async, etc.
no funcionarán (también son un patrón de diseño muy pobre y extremadamente cojo)
- este es su main.js
donde está inyectando dinámicamente su código en el DOM (por ejemplo, creando un bookmarklet o algo así):
/**
* loads the base.js of google closure.
* http://code.google.com/p/closure-library/
*/
(function() {
var s = document.createElement(''script'');
s.type = "text/javascript";
s.src = "./assets/closure/goog/base.js";
s.async = true;
document.getElementsByTagName("body")[0].appendChild(s);
}());
/**
* activated from the base.js as JSONProtocol.
*/
window[''starter''] = function() {
console.log("hi...");
};
ahora:
- edita tu
base.js
agrega el final del archivo
......
.......
........
/**
* run the method when done load. just like JSONProtocol.
*/
window.setTimeout(function() {
window[''starter'']();
}, 5);
su " devolución de llamada " simplemente activa el iniciador cuando el archivo ha terminado de renderizarse,
Funciona perfectamente y sigue cargando todos los recursos de forma asíncrona.
PD
- La sintaxis de la ventana [''....''] es para que pueda usar con seguridad el cierre-compilador al máximo y usar siempre el mismo nombre (aunque hay otras formas de hacerlo, pero esta es la forma simple "siempre funciona". .).
2. en base.js
también puede evitar el tiempo de espera y simplemente usar
......
.......
........
/**
* run the method when done load. just like JSONProtocol.
*/
window[''starter'']();
pero como regla general, los navegadores modernos actúan mejor cuando los ajustas "no importa, solo haz esto al final, como JSONProtocol callback"
los tiempos de espera (en su mayoría utilizados con valores de 0 a 5) no se interrumpen como tiempos de espera, sino como una forma de interrumpir la sincronicidad del bloque de código, lo que permite un comportamiento similar al "cambio de contexto".
aunque hay una sobrecarga adicional allí.