Three.js: ¿Archivo "externs" del compilador de cierre de Google para three.js?

Creado en 10 jul. 2011  ·  61Comentarios  ·  Fuente: mrdoob/three.js

Hola

¿Hay algún archivo externo para three.js? Me refiero a uno:

http://code.google.com/closure/compiler/docs/api-tutorial3.html#externs

Gracias
Remo

Question

Comentario más útil

Hmmm, todavía no estoy muy contento con tener toneladas de comentarios en el código. A veces me pregunto si no sería mejor portar todo a algo como TypeScript (lástima que uno sea propiedad de Microsoft).

Todos 61 comentarios

No, three.js no tiene dependencias externas, por lo que algo como esto no era necesario hasta ahora.

Lo sé, pero también es útil para proyectos propios integrar THREE.js en un entorno compilable.

¿Cómo se vería ese archivo? Lo siento si ya está explicado en el enlace que compartiste, encontré la página un poco abrumadora (demasiado texto) y no puedo leer / entender.

@mrdoob , encontrará algunos de sus ejemplos en:

http://code.google.com/p/closure-compiler/source/browse/#svn% 2Ftrunk% 2Fexterns

o

http://code.google.com/p/closure-compiler/source/browse/#svn% 2Ftrunk% 2Fcontrib% 2Fexterns

y lo siguiente también es importante:

http://code.google.com/closure/compiler/docs/js-for-compiler.html

Comentarios / Encabezados? Creo que eso haría que el código fuera más difícil de leer ...

Sí, pero creo que es solo para este archivo externo, no para todo el código. Uno puede hacerlo, pero no es necesario.

Lo probé con http://www.dotnetwise.com/Code/Externs/index.html . Pero no funciona completamente con Three.js. No se extraen todas las definiciones.

Aquí está la entrada del blog:

http://blog.dotnetwise.com/2009/11/closure-compiler-externs-extractor.html

Parece que admite el patrón this.method = function(){} , pero no los prototipos ...

@mrdoob , ¿cuál es su recomendación para integrar THREE.js en una aplicación propia con optimizador avanzado del compilador de cierre? ¿Es cierto que actualmente no es posible?

Por lo que tengo entendido, el optimizador avanzado solo incluye las clases que se utilizan, ¿verdad? En teoría debería funcionar ... ¿no está funcionando?

No probé la optimización avanzada con three.js, pero recuerdo otras cosas que solía romper el código. En general, no era "seguro": con la optimización simple predeterminada siempre funciona, con la avanzada a veces no.

Rompe el código si lo compila como una biblioteca, pero como una aplicación (con los métodos que se llaman y todo eso) debería funcionar, ¿verdad?

@mrdoob para usar una biblioteca con código compilado (optimizado), necesita un archivo "externo" para declarar todas las clases y métodos de la biblioteca. No funciona sin él. Pero, ¿hay otra herramienta que funcione con three.js? Lo necesito para ofuscar (uglify) mi aplicación three.js. Un candidato es: https://github.com/mishoo/UglifyJS . Pero no lo he probado.

Externos de cierre de Google es un archivo, que describe objetos completos, que usaremos en nuestro código compilado.
Sin este archivo, el compilador solo hace de los nombres de las funciones algo como a () o b ().

Por ejemplo, esto es para JQuery: http://code.google.com/p/closure-compiler/source/browse/trunk/contrib/externs/jquery-1.7.js

Sería genial si los externos fueran por three.js.

Estoy bien con eso, pero no puedo abordarlo yo mismo. Alguien más tendrá que intensificar este.

@yurikor , cuando usa node.js, puede usar node-browserify y uglify-js juntos. Entonces no necesitas construir nada.

@remoe Muchas gracias por el consejo. Lo intentaré.

Este problema ha estado inactivo durante un tiempo, pero en caso de que alguien quiera abordar este problema en el futuro, aquí hay información adicional:

Para mi proyecto, he creado un archivo simple con solo suficientes exportaciones de threejs para poder compilar mi proyecto. Viene con anotaciones de tipo que fue bastante útil ya que permitió al compilador de cierre verificar todos los tipos y encontrar un par de errores en mi código. He creado este archivo manualmente. Utilizo el compilador de cierre principalmente para comprobar errores, para la minificación real utilizo los uglifyjs menos potentes pero seguros.

Además, para evitar que el compilador de cierre cambie el nombre de mis símbolos de interfaz pública, tuve que agregar varias líneas de código (esas cuatro funciones son las únicas funciones públicas de mi biblioteca). Tenga en cuenta que el compilador de cierre cambia el nombre de todas las propiedades a las que se accede a través de blah.xyz , pero no toca ninguna propiedad a la que se accede a través de blah["xyz"] .

Finalmente, se necesitaba la línea window['ColladaLoader2'] = ColladaLoader2 (observe nuevamente el uso de una cadena) para decirle al compilador de cierre que esta clase debe exportarse al ámbito global.

¿Pero no está utilizando el cierre para la producción y solo la verificación de errores? yo soy
No estoy seguro de si vale la pena mantener el archivo externo. Solo ejecuta el cierre
sin optimizaciones agresivas y luego no necesita el archivo externo
pero todavía obtienes la mayor parte de la validación, creo, o tal vez todos los
validación. ¿Quizás puedas aclarar?

Enviado desde mi teléfono, perdón por mi gramática y concisión.
El 12 de febrero de 2013 a las 5:19 a. M., "Robert Carnecky" [email protected] escribió:

Este problema ha estado inactivo durante un tiempo, pero en caso de que alguien quiera
abordar este problema en el futuro, aquí hay información adicional:

Para mi proyecto, he creado un archivo simple
con anotaciones de tipo que fue bastante útil ya que permitió el cierre
compilador para comprobar todos los tipos y encontrar un par de errores en mi código. yo tengo
creó este archivo manualmente. Utilizo el compilador de cierre principalmente para errores
comprobando, para la minificación real utilizo el menos poderoso pero seguro
uglifyjs https://github.com/mishoo/UglifyJS.

Además, para evitar que el compilador de cierre cambie el nombre de mi interfaz pública
símbolos, tuve que agregar varias líneas de código https://github.com/crobi/ColladaAnimationCompress/blob/366344d3aa5dbbc0a53c47a2c1759b86bb1e0fcd/ColladaLoader2.coffee#L3376 (esas cuatro funciones son las únicas funciones públicas de mi biblioteca). Nota
que el compilador de cierre cambia el nombre de todas las propiedades a las que se accede a través de blah.xyz,
pero no toca ninguna de las propiedades a las que se accede a través de blah ["xyz"].

Finalmente, la líneahttps: //github.com/crobi/ColladaAnimationCompress/blob/366344d3aa5dbbc0a53c47a2c1759b86bb1e0fcd/ColladaLoader2.coffee#L3383 ventana ['ColladaLoader2']
= ColladaLoader2 (tenga en cuenta de nuevo el uso de una cadena) era necesario para decirle al
compilador de cierre que esta clase debe exportarse al ámbito global.

-
Responda a este correo electrónico directamente o véalo en Gi

Hasta donde yo sé, el modo simple no realiza ninguna validación. Cambia el nombre de las variables locales y, si encuentra un símbolo desconocido, lo deja intacto, asumiendo que es una variable global.

El modo avanzado se comporta como un compilador en un lenguaje fuertemente tipado (asumiendo que la información de tipo está disponible): advierte sobre funciones o propiedades desconocidas, advierte si llamó a una función con el número incorrecto de argumentos o si ha utilizado un parámetro de cadena donde un se esperaba un número.

Como ejemplo, el modo simple transforma el siguiente código

function fn() {
    var foo = {}; // local variable, safe to rename this
    foo.bar();    // undefined property, will crash here
}
fn();

sin ninguna advertencia en

function fn(){({}).bar()}fn();

que obviamente se bloqueará en ({}).bar() . El modo avanzado genera el siguiente código

({}).a(); // fn() inlined, private member 'bar' renamed to 'a'

que todavía falla, pero el compilador también da una advertencia

Property bar never defined on foo at line 3 character 0.
  • El cierre de errores encontrado fue el tipo de error en el que tuve un error tipográfico en el nombre de una función o en el que pasé un THREE.Vector3 a Matrix4.makeTranslation lugar de tres números separados para los componentes x, y, z .
  • Si tuviera una cobertura de prueba completa (que no tengo), habría encontrado esos errores tarde o temprano. Sin embargo, a veces son difíciles de depurar si no se manifiestan de inmediato.
  • Si threejs proporcionó un archivo de exportación actualizado con cada nueva versión (gran esfuerzo de mantenimiento), el compilador de cierre detectaría todos los problemas que surgen de una API cambiante (como fue el caso de Matrix4.makeTranslation ).
  • Configurar el compilador de cierre es demasiado trabajo para mí, ya que necesita un tiempo de ejecución de Java. Todas las demás herramientas necesarias para construir mi biblioteca se basan en node / javascript.

Actualmente estoy construyendo mi archivo externs.js de la biblioteca de cierre para integrar una aplicación THREE.js con la biblioteca de cierre. Básicamente, lo que estamos tratando de averiguar es:
¿Hay una lista en alguna parte de todas las clases THREE.js y los métodos prototipo que implementan? La lista debería ser algo como esto:

TRES Textura
TRES.constructor.de.textura
TRES.Textura.clon
TRES.Textura.disponer
TRES.DataTexture.clone

(etcétera...)

Ps- Three.js es genial, pero con los jsDocs adecuados, esta lista podría extraerse fácilmente :)

Tengo una implementación parcial de las exportaciones de three.js aquí (escrito manualmente, por lo que puede contener algunos errores).

@crobi : ¿por qué le pusiste los comentarios del documento? Parece que tomó bastante tiempo y no estoy seguro de que sea necesario ...

@taoeffect : los comentarios son principalmente para el modo avanzado del compilador de cierre. Me gusta el código fuertemente tipado.

@crobi , oh, ¿los comentarios resultan en una escritura forzada? Eso es algo genial, no sabía que hiciera eso.

Solo si usa el compilador de cierre para verificar errores de tipo. Similar al mecanografiado . Ambos preprocesan javascript anotado en javascript simple. Por lo tanto, es solo una verificación en tiempo de compilación.

La mayoría de los comentarios sobre el modo de optimizaciones avanzadas del cierre aquí son inexactos.

Para abordar el problema principal, puede utilizar la siguiente herramienta para generar automáticamente cierres externos para cualquier biblioteca http://www.dotnetwise.com/Code/Externs/

Además, si decide usar three.js como entrada para su código en lugar de simplemente usarlo como una biblioteca externa, deberá agregar la marca

--language_in=ECMASCRIPT5

Deberías escribir una publicación de blog sobre esto, tal vez haciendo una presentación.
ejemplo crítico y ver si lo ejecuta a través del cierre de Google
El compilador con buenas optimizaciones marca la diferencia.
-ben

El lunes 13 de enero de 2014 a las 12:31 p.m., Rodrigo Formigone <
[email protected]> escribió:

Además, si decide usar three.js como entrada para su código en lugar de
simplemente usándolo como una biblioteca externa, deberá agregar la bandera

--language_in = ECMASCRIPT5

-
Responda a este correo electrónico directamente o véalo en Gi
.

Atentamente,
Ben Houston
Voz: 613-762-4113 Skype: ben.exocortex Twitter: @exocortexcom
http://Clara.io - Creación de contenido 3D basado en WebGL de nivel profesional

Supongo que podría escribir una publicación así. Sin embargo, solo para aclarar, la razón por la que uno querría ejecutar Three.js a través del cierre (con o sin un archivo externo) no es necesariamente solo por las optimizaciones de rendimiento. El cierre está destinado principalmente a ayudarlo a escribir código mantenible en JavaScript (en particular, bases de código muy grandes). El objetivo es ayudar a los desarrolladores a "domesticar" JavaScript (escribiendo JS nativo), en lugar de "evitarlo" (utilizando GWT u otras herramientas similares). Si simplemente intenta compilar Three.js como parte de un proyecto de cierre, el compilador podría gritarle porque Three.js podría no cumplir con algunos de sus estándares (¿tal vez no lo suficiente JSDoc?). El uso de la bandera del compilador --language_in resuelve eso a partir de ahora, aunque recibirá algunas advertencias. Si simplemente desea compilar su propio código JS, pero haga referencia a Three.js como una biblioteca externa (dejando así todo el código base de Three.js intacto y sin optimizar), necesitará el archivo externo mencionado anteriormente. Sin el archivo externs, Closure arrojará errores de compilación diciendo que THREE. * No se declara en ninguna parte, etc.

Si bien no puedo escribir la publicación de mi blog explicando cómo y por qué uno podría querer usar Three.js en un proyecto de cierre, aquí está la mejor presentación introductoria sobre las herramientas de cierre de Google que he visto: (De Google I / O 2011) https://www.youtube.com/watch?v=M3uWx-fhjUc (Sé que es un video largo, pero realmente deja en claro cuál es el propósito del compilador y qué hacen realmente los diferentes modos de compilación. También describe por qué necesitarías un archivo externo).

Hola, estoy deseando desarrollar una aplicación usando three.js y, por lo tanto, deseo que sea compatible con la opción ADVANCED_OPTIMIZATIONS.

La eliminación de código muerto funciona fuertemente cuando la aplicación de incrustación usa solo una parte de las funciones de Three.js.

Actualmente, three.js requiere que se desarrollen todas las funciones, porque el uso previsto se limita a "¡Solo requiere three.min.js!". Este enfoque clásico es fácil de entender, pero para los códigos escritos con este enfoque, los minimizadores de JavaScript pueden reducir el código. tamaño solo reduciendo los nombres de variables (no es efectivo para nombres de variables cortos), eliminando espacios (solo efectivo para espacios de sangría, tabulaciones y saltos de línea) y otros trucos baratos.

Al usar la opción ADVANCED_OPTIMIZATIONS para un código de "estilo de compilador de cierre", puede eliminar todos los "códigos no necesarios", que en su mayoría pesan bibliotecas grandes. Las bibliotecas como la biblioteca Closure se han vuelto grandes, pero a los usuarios y desarrolladores de bibliotecas no les importa porque saben que la mayor parte del código se eliminará en la etapa de compilación.

Dado que three.js ya está escrito en estilo orientado a objetos, creo que no es (técnicamente) difícil actualizar todo el código al código de "estilo de compilador de cierre". Las cosas que me preocupan ...

  • El estilo del compilador de cierre requiere anotaciones para cada función. Actualmente, no hay ninguno de ellos. ¿Cuánto tiempo llevará agregar anotaciones a todas las funciones desarrolladas?
  • El compilador de cierre requiere definiciones de tipo estrictas. Incluso para nulos e indefinidos, debería trabajar para ellos correctamente. Puede ser un trabajo duro para las funciones que tienen parámetros "nulos permitidos", parámetros "no definidos permitidos", ...
  • Debe preparar un archivo externo adecuado, si está deseando preparar la "biblioteca con versión completa" compilada por ADVANCED_OPTIMIZATIONS.

Hai Schedul Xor,

Esta es una buena idea. ¿Podría compartir un pequeño fragmento sobre cómo
esto tiene que agregarse a three.js?

Con saludos,

Ramsundhar Madhavan

El martes, 24 de junio de 2014 a las 4:23 p.m., Schedul Xor [email protected]
escribió:

Hola, estoy deseando desarrollar una aplicación con three.js y
por lo que desea el soporte de la opción ADVANCED_OPTIMIZATIONS.

La eliminación de código muerto funciona fuertemente cuando la aplicación de incrustación solo usa
una parte de las funciones de Three.js.

Actualmente, three.js requiere que se desarrollen todas las funciones, porque el
el uso previsto se limita a "¡Solo requiere tres.min.js!". Este clásico
El enfoque es fácil de entender, pero para los códigos escritos por este enfoque,
Los minimizadores de JavaScript pueden reducir el tamaño del código solo reduciendo los nombres de las variables
(no es efectivo para nombres de variable cortos), eliminando espacios (solo efectivo
para espacios de sangría, tabulaciones y saltos de línea) y otros trucos baratos.

Mediante el uso de la opción ADVANCED_OPTIMIZATIONS en un "Compilador de cierre con estilo"
código, puede eliminar todos los "códigos no necesarios", que en su mayoría pesan
grandes bibliotecas. Bibliotecas como la biblioteca Closure
https://developers.google.com/closure/library/ se había vuelto grande, pero
a los usuarios y desarrolladores de bibliotecas no les importa porque saben que
la mayor parte del código se eliminará en la etapa de compilación.

Dado que three.js ya está escrito en estilo orientado a objetos, creo que es
no es (técnicamente) difícil actualizar todo el código a "Closure compiler
código de estilo ". Las cosas que me preocupan ...

  • El estilo del compilador de cierre requiere anotaciones para cada función.
    Actualmente, no hay ninguno de ellos. ¿Cuánto tiempo llevará agregar anotaciones?
    a todas las funciones desarrolladas alguna vez?
  • El compilador de cierre requiere definiciones de tipo estrictas. Incluso para nulos y
    undefined, deberías trabajar para ellos correctamente. Puede ser un trabajo duro para
    funciones que tienen parámetros "nulos permitidos", "indefinidos permitidos"
    parámetros, ...
  • Debe preparar un expediente externo adecuado, si está mirando hacia adelante
    para preparar la "biblioteca con versión completa" compilada por
    ADVANCED_OPTIMIZATIONS.

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/mrdoob/three.js/issues/341#issuecomment -46957189.

@ schedul-xor definitivamente necesitamos ayuda con eso ... ¿son realmente necesarias las anotaciones de código o es suficiente con los externos?

Hola,

Soy nuevo en esta comunidad, me interesaría contribuir con estos
cambios.

Con saludos,

Ramsundhar Madhavan

El martes 24 de junio de 2014 a las 7:23 p. M., Mr.doob [email protected] escribió:

@ schedul-xor https://github.com/schedul-xor definitivamente necesitamos ayuda
con eso ... ¿son realmente necesarias las anotaciones de código o es suficiente con
externos?

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/mrdoob/three.js/issues/341#issuecomment -46973166.

Tenga en cuenta que las optimizaciones avanzadas requieren un cierto estilo de codificación o romperán su código. Por ejemplo, three.js mezcla uniforms["diffuse"] y uniforms.diffuse , lo que no está permitido en las optimizaciones avanzadas de cierre. Vea también # 3222.

Agregar anotaciones de tipo estricto en todas partes es una gran cantidad de trabajo y agrega muchas líneas de comentarios (en mi proyecto, aumentó el recuento de líneas en un factor de 2).

Tener archivos externos para otros marcos / lenguajes web es bueno.

Según el tutorial , los externos se utilizan para proteger las variables que no desea que se les cambie el nombre. Esto es lo que usa cuando desea proteger bibliotecas de terceros (con estilo de compilador sin cierre), utilizando en su proyecto con estilo de compilador de cierre, de cambios de nombre de variables agresivos.

No estoy seguro de si el compilador seguirá intentando cortar el código muerto incluso cuando el archivo externo es lo único que se proporciona. Será mucho más fácil si solo debe escribir archivos externos, en lugar de escribir anotaciones en todas las funciones ...

Aunque, en mi opinión, escribir anotaciones para cada función es mejor que escribir externos, porque será difícil sincronizar el archivo externo después, si el archivo de definición de tipo y el código fuente son diferentes. Puede imaginar lo molesto que será si cada corrección de función requiere una actualización de archivos externos. Cualquiera de las opciones (externos o / ** * / comentar sobre funciones) requiere anotación, en la mayoría de los casos gana el método más fácil.

Dado que three.js es un proyecto grande, me pregunto dónde debería trabajar primero. Será mejor comenzar por lo que se puede hacer fácilmente.

¿Qué tal poner encabezados de archivo, cambiar el estilo de definición de función para cada función?

THREE.Material = function(){
  :
};
THREE.Material.prototype = {
    constructor: THREE.Material,
    setValues: function ( values1, value2 ) {}
    getValues: function () { return this.a; }
    :
};

goog.provide('THREE.Material'); ← Write goog.provide('package.classname') at the first line

← three empty lines before <strong i="10">@constructor</strong>

/**
 * <strong i="11">@constructor</strong> ← Add <strong i="12">@constructor</strong> annotation to constructor
 */
THREE.Material = function(){
  :
};

← two empty lines before function definition
/**
 * <strong i="13">@param</strong> {!Array.<!string>} values1 Values1 explanation ← values1 is an array of strings. values1 can't be null, and elements inside values1 can't be null.
 * <strong i="14">@param</strong> {!number} value2 Value2 explanation ← value2 is a number.
 */
THREE.Material.prototype.setValue = function(values1, value2){
  goog.asserts.assertArray(values1);
  goog.asserts.assertNumber(value2);
  :
};


/**
 * <strong i="15">@return</strong> {!number} ← This function returns a non-null number.
 */
THREE.Material.prototype.getValue = function(){
  return this.a;
};

Será más fácil restringir todos los tipos de parámetros y devolver los tipos de valor a valores no nulos. Esto hará que sea mucho más fácil pasar errores de compilación ADVANCED_OPTIMIZATIONS.

Hmmm, todavía no estoy muy contento con tener toneladas de comentarios en el código. A veces me pregunto si no sería mejor portar todo a algo como TypeScript (lástima que uno sea propiedad de Microsoft).

TypeScript se siente mucho mejor para javascript fuertemente tipado que para el cierre. Esta es mi experiencia después de haber reescrito un cargador collada de tamaño moderado primero en javascript compatible con el cierre y luego en mecanografiado. Ambos enfoques ayudaron a encontrar errores en el momento de la compilación. Closure realizó algunas optimizaciones bastante buenas (alineación, eliminación de código muerto) de mi código y tiene soporte para tipos que aceptan valores NULL. Por otro lado, la gran cantidad de comentarios distraía y el soporte IDE (para completar el código) no era tan bueno como con el mecanografiado. Además, escribir clases en mecanografiado es mucho más fácil debido a la palabra clave class similar a ECMAScript6.

Pero esa es solo una opinión personal. Más importante aún, quiero enfatizar nuevamente el hecho de que debe asegurarse de que todos los accesos a la propiedad sean consistentes antes de admitir oficialmente el cierre en el modo de compilación avanzada. Tener un archivo externo no ayuda, el acceso a la propiedad debe ser coherente para los objetos internos que no se exportan, ya que _desea_ que se les cambie el nombre / alinee / elimine de forma agresiva. Detectará accesos de propiedad inconsistentes si anota cada clase y cada variable, pero hacer esto para la base de código three.js completa es de varias semanas de tiempo (si extrapolo cuánto tiempo me tomó anotar mi proyecto).

Finalmente, trasladar un proyecto tan grande como three.js a cualquier otro lenguaje / marco / estilo de codificación es algo que debería discutirse en detalle.

De acuerdo, estoy de acuerdo en que three.js es enorme, por lo que agregar anotaciones a cada función puede llevar varias semanas. Puede que existan mejores AltJS que el cierre. Esto debe discutirse (si está deseando trasladarlo a otra cosa) más profundamente.

Lo siento, no puedo esperar. Bifurcaré la confirmación actual y comenzaré a portar.

Hola,

¿Es posible automatizar la adición de estas anotaciones? Si es así, podemos agregarlas
para build.py y agregar justo antes de que habilitemos la optimización avanzada del cierre.

Con saludos,

Ramsundhar Madhavan

El miércoles, 25 de junio de 2014 a las 6:05 a. M., Schedul Xor [email protected]
escribió:

De acuerdo, estoy de acuerdo en que three.js es enorme, por lo que agregar anotaciones a cada
las funciones pueden tardar varias semanas. Puede que existan mejores AltJS que
cierre. Esto debe discutirse (si está deseando trasladarlo a
algo más) más profundamente.

Lo siento, no puedo esperar. Bifurcaré la confirmación actual y comenzaré a portar.

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/mrdoob/three.js/issues/341#issuecomment -47047966.

@ ramsundhar20 , en mi opinión, agregar anotaciones (¿inexactas? mejor que nada. No es un gran problema. Se puede actualizar) primero hará que la automatización sea mucho más fácil.

Three.js contiene actualmente 163 archivos javascript con 1354 funciones definidas. Sí, es enorme, pero no es una meta que esté demasiado lejos.

// Tengo miedo si este tema está fuera de lugar ...

@ schedul-xor de nuevo, no soy realmente un fanático de tener un comentario por función: /

@mrdoob OK, lo entendí.

Respetando su política, me gustaría agregar comentarios por función solo en mi bifurcación. Además, nunca realizaré solicitudes de extracción. En su lugar, migraré las modificaciones originales de three.js a mi horquilla con estilo de cierre. Agradeceríamos su consideración favorable.

Eso suena bien :)

¡Gracias! Empezaré a trabajar en eso.

¿Hay al menos un archivo externo base three.js para usar con el compilador de cierre? Eso no requiere que el código fuente de Three.js tenga anotaciones de estilo de Google adicionales, esto es solo para hacer que el enlace desde un app.js externo que usa three.js sea lo suficientemente compilable / ofuscado.

También estoy muy interesado en un archivo externo completo y de calidad para three.js. Aquí hay uno, pero no está completo:

https://github.com/cljsjs/packages/blob/master/three/resources/cljsjs/three/common/three.ext.js

Supongo que una forma de hacerlo es comenzar con este y agregar manualmente las cosas que usa.

Sí, cuente mi voto. Idealmente para un modo avanzado compilable, threejs 100% tipeado, o un archivo externo como mínimo.

La inferencia de tipos ha mejorado y el desorden requerido se ha reducido. Con ámbitos y alias en su lugar, el código no tiene que leerse tan detallado como la biblioteca de cierre. Básicamente se reduce a escribir documentos en línea mecanografiados en caso de código limpio. ¿Son esos realmente lo suficientemente malos como para superar todos los beneficios?

Las configuraciones súper agresivas, es decir, modo avanzado + compresión JS + optimizaciones basadas en tipos, no solo eliminarán el código muerto, sino que pueden hacer todas las cosas interesantes que puede hacer un compilador optimizador:

Las constantes / enumeraciones con nombre se reemplazarán con números. Además, el compilador puede rastrear la constness, realizar cálculos con otras constantes y finalmente insertar un número simple donde sea necesario. El control de flujo dependiente está sujeto a la eliminación de códigos muertos, por supuesto. Las funciones que solo tienen un sitio de llamada activo en la aplicación resultante y aquellas cuya forma comprimida terminará siendo más pequeña de lo que ahorraría su definición, se incluirán en línea. Se eliminan los espacios de nombres. Todos los nombres desprotegidos se reducen al mínimo.

La búsqueda es comparativamente cara en JavaScript. La combinación de cambio de nombre, plegado constante e inserción eliminará muchas búsquedas y numerosas llamadas a funciones. Además de eso, dado un encabezado apropiado (hay uno en la biblioteca de cierre), todas las constantes de WebGL estandarizadas se pueden integrar en el renderizador.

El resultado es una biblioteca más pequeña, más rápida, autodocumentada y automáticamente personalizable. El compilador también detectará muchos más errores en configuraciones más agresivas; probablemente facilitará la revisión del código. Por último, pero no menos importante, está el efecto de ofuscación: agrupar el código del cliente con la biblioteca personalizada proporciona una protección mucho mejor contra el robo de propiedad intelectual que el código con símbolos reveladores que se conservaron mediante un archivo externo.

No puedo encontrar la rama mencionada anteriormente. ¿Alguien todavía está trabajando en una versión mecanografiada?

@mrdoob ¿ Alguna esperanza de un cambio de opinión con respecto a la línea principal?

Estaré feliz de ayudar.

@mrdoob ¿ Alguna esperanza de un cambio de opinión con respecto a la línea principal?

Por el momento me estoy enfocando en refactorizar WebGLRenderer 😇

Puede cambiar las constantes a const lugar de var tiene un buen soporte para todos los navegadores WebGL https://kangax.github.io/compat-table/es6/ (const-> basic) y js los motores están comenzando a optimizar por const Acelerando las constantes globales usando la optimización de campo fijo

Sin embargo, es interesante, ya que solo funciona en lugar de var , solo se aplica a una fracción muy pequeña de los casos de los que estoy hablando, incluso cuando se trata solo de constantes. Además, los compiladores JIT tienen prisa por definición, por lo que, naturalmente, no pueden competir con las optimizaciones del programa completo realizadas por una herramienta fuera de línea. Cada motor JS debe respetar la estructura del código y no puede refactorizarlo arbitrariamente, ya que esperamos poder, por ejemplo, abrir la consola y encontrar el programa que ponemos en ella, reemplazar una función específica, etc.

Volver al soporte del compilador de cierre: hice algo de lectura y experimentación. Esto es lo que descubrí:

  • No se requieren anotaciones para ejecutar el modo avanzado,
  • Las anotaciones se pueden agregar gradualmente para aumentar el nivel de optimización, y
  • el cargador necesita algo de cuidado para seguir funcionando, pero es bastante fácil.

Básicamente, hay tres casos de uso diferentes:

  1. Los modelos se pueden comprimir junto con la aplicación y la biblioteca.
  2. La aplicación y la biblioteca están comprimidas. Los modelos se cargan en tiempo de ejecución.
  3. La biblioteca está compilada en modo básico y una aplicación de modo avanzado quiere usarla.

El tercero requiere un archivo externo para todos los Three.js y es mucho trabajo por muy poco beneficio, en mi opinión. Así que solo discutiré los dos primeros, estos son los preferidos, de todos modos:

Cuando el compilador ve

anObject['aProperty']

no tocará el nombre de la propiedad (nunca se cambian las cadenas).

anObject.aProperty

por otro lado, permite al compilador cambiar el nombre de la propiedad de manera consistente, a menos que sepa que anObject es externo a la aplicación que se está compilando. El compilador sabe esto a partir de _externs_ incorporados o proporcionados explícitamente.

Aquí viene la receta:

  • Hacemos que el cargador acceda constantemente a las propiedades utilizando la notación de puntos.
  • Escribimos la entrada y escribimos un archivo externo solo para JSON .
  • La compilación con ese archivo externo debería ser todo lo que se necesita para que funcione el caso de uso 2.
  • Para el caso de uso 1, no usamos el archivo externo, sino que eliminamos las comillas de las claves del objeto en el JSON:
{
    "camera": {
        "object": {
    // ...

simplemente se convertiría en

{
    camera: {
        object: {
    // ...

Muy simple, ¿no?

El caso de uso 1 se vuelve aún más atractivo cuando el formato JSON permitiría datos binarios externos (sin procesar o comprimidos a través de webgl-loader o o3dgc), técnicamente otra característica completamente ortogonal al soporte de cierre, por supuesto.

El archivo externo también puede reemplazar las páginas Wiki obsoletas que documentan el formato de archivo :-).

Sé que este problema ha estado cerrado durante bastante tiempo. Sin embargo, recientemente tuve el mismo problema al usar three.js dentro de un proyecto de compilador de cierre y llegué a esta página. Escribí una herramienta que transforma .d.ts (archivos de declaración mecanografiada) en un archivo compilador de cierre. Usando la herramienta y el gran archivo descriptor DefinitelyTyped / threejs descrito, funciona perfectamente.
La herramienta: https://github.com/eredo/tsd2cce o instálela a través de npm install -g tsd2cce

Espero que esto ayude...

@eredo eso me ayudó totalmente. A todos los demás generadores que probé les faltaba una buena cantidad de definiciones de métodos para la biblioteca three.js. ¡Gracias!

@eredo @Corkle o cualquier otra persona, ¿puede mostrarnos cómo usar tsd2cce ? El primer argumento es claramente el archivo de definición .d.ts, pero ¿cuál es el segundo argumento? Tengo este problema. https://github.com/eredo/tsd2cce/issues/6

En realidad, descubrí que usar el r73 d.ts de febrero funciona bien con tsd2cce, aunque r73 es demasiado viejo para mí.

La forma correcta de hacer esto ahora sería usar tsickle para generar archivos d.ts.

Oigan todos,

Para la posteridad y el beneficio de todos, decidí informar aquí sobre mis propios intentos de reducir aún más la biblioteca con ADVANCED_OPTIMIZATIONS del compilador de cierres de Google y algunos otros ajustes.

He creado un extern.js que permite Three.min.js con optimizaciones avanzadas activadas. Está lejos de ser perfecto.

Para crearlo, comencé con un extern.js basado en ejemplos anteriores en este hilo. La biblioteca se rompió cuando se compiló de esta manera debido a propiedades dañadas no incluidas en ese archivo externo. Usando la opción --property_renaming_report en el compilador de cierre, obtuve la lista completa de propiedades destrozadas. Después de agregar TODAS estas propiedades a extern.js, las propiedades ya no se modificaron y el resultado fue el mismo que SIMPLE_OPTIMIZATIONS. A partir de ahí, comencé a comentar de forma selectiva / manual secciones de extern.js y a confirmar que la biblioteca todavía funcionaba en forma reducida.

Me ENCANTARÍA automatizar esta conjetura y verificación y obtener un extern.js perfecto que destruya de forma segura tantos nombres de propiedad como sea posible. Tuve la idea de usar las pruebas unitarias para THREE.JS y determinar programáticamente qué nombres de propiedad alterados resultaron en pruebas fallidas, pero no parece posible ejecutar las pruebas unitarias desde la línea de comandos actualmente, por ejemplo, con phantomjs. (Probablemente debido a WebGL)?

De cualquier manera, esto es un "progreso" hacia una biblioteca minificada más pequeña, lo que me ayuda a mantener bajo el tamaño general de javascript de SPA.

externs.js

comando de cierre de compilación package.json actualizado

También utilicé comandos de reemplazo de cadenas para eliminar todos los mensajes console.warn y console.error de la biblioteca, como puedes ver en el comando build-closings. Con esto, y comentando ciertas secciones de código, he reducido la biblioteca minificada en aproximadamente un 20% hasta ahora, y hay margen de mejora.

@mrdoob Al hacer algo como mi método aquí, eventualmente podría proporcionar un extern.js que permita ADVANCED_OPTIMIZATIONS sin saturar el código con anotaciones específicas para ese compilador, que parecía ser su principal preocupación.

@ medmr1 ¡Impresionante! ¿Ha intentado compilar su aplicación con la biblioteca three.js todo en uno? Idealmente, esto evitaría la necesidad de un archivo externo.

No he intentado construir todo dentro del cierre, no. Eso puede funcionar bien, pero sospecho que todavía habrá problemas con respecto a la manipulación de algunas propiedades a las que se hace referencia mediante programación. IE cosas como var thing = ShaderLib[ shaderType + "BumpMapFrag"] Pero tal vez me ahorraría muchos problemas?

Sí, algo como var thing = ShaderLib[ shaderType + "BumpMapFrag"] se romperá con optimizaciones avanzadas. las referencias de propiedad deben ser analizables estáticamente. Podrías hacer algo como:

function(shaderType) {
  if (shaderType == "a") {
    return ShaderLib.aBumpMapFrag;
  }
  if (shaderType == "b") {
    return ShaderLib.bBumpMapFrag;
  }
...

La construcción de un archivo externo correcto es definitivamente más beneficioso para el proyecto en su conjunto, ya que la mayoría de la gente no compilará su aplicación con Closure Compiler, solo usará la versión minimizada publicada.

En lugar de externos, también puede probar la anotación @export .
https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#export -export-sometype

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

fuzihaofzh picture fuzihaofzh  ·  3Comentarios

jlaquinte picture jlaquinte  ·  3Comentarios

zsitro picture zsitro  ·  3Comentarios

Horray picture Horray  ·  3Comentarios

makc picture makc  ·  3Comentarios