Three.js: Evaluar clases de ES6

Creado en 19 jun. 2017  ·  92Comentarios  ·  Fuente: mrdoob/three.js

¿Por qué se introduce este 'modismo' de herencia en el código?

PointLight.prototype = Object.assign( Object.create( Light.prototype ), {

¿Seriamente? Función (Función anidada (Prototipo principal) COMA SOPORTE DE ESCOPETA?

El fiel estilo de dos líneas todavía en, por ejemplo, las clases de Materiales es mucho más claro y limpio. Asigne el prototipo y luego establezca el constructor. El fin. Por favor, no arruine la biblioteca al contraer la enfermedad de JavaScript: la extraña necesidad de masturbarse en la forma en que se codifican los objetos y la herencia. Un estilo en toda la biblioteca. No hay necesidad de cambiarlo.

Suggestion

Comentario más útil

Hasta que los navegadores puedan ejecutar TypeScript de forma nativa, prefiero seguir usando JavaScript.

Todos 92 comentarios

Entonces, ¿estás sugiriendo usar este patrón en su lugar?

PointLight.prototype = Object.create( Light.prototype );
Object.assign( PointLight.prototype, {
class PointLight extends Light

jeje 😄 Y sin problemas...

@sasha240100 algún día...

@mrdoob no del todo: las dos formas que mencionas son directamente equivalentes. Creo que el OP está comparando

PointLight.prototype = Object.assign( Object.create( Light.prototype ), { 
    constructor: PointLight,
    prop1: 'something',
    method1: function someFunction() { .. },
    ...
});

con

function PointLight () { ... };

PointLight.prototype = Object.create( Light.prototype );

PointLight.prototype.constructor = PointLight;

PointLight.prototype.prop1 = 'something';

PointLight.prototype.method1 = function someFunction() { .. };

...

Que es la forma en que se hace aquí, por ejemplo.
Por lo que puedo ver, estos estilos son equivalentes. ¿Hay algo que me estoy perdiendo?
¿O se cambió el estilo para usar Object.Assign una vez que estuvo disponible y no se actualizó en la base de código?

@looeee @bfred-it @mrdoob ¿Por qué no usar rollup-babel ?

Comparación :
Actual. Módulos de armonía es5 + es6.

import { LineBasicMaterial } from './LineBasicMaterial';
import { Color } from '../math/Color';

function LineDashedMaterial( parameters ) {

    LineBasicMaterial.call( this );

    this.type = 'LineDashedMaterial';

    this.scale = 1;
    this.dashSize = 3;
    this.gapSize = 1;

    this.setValues( parameters );

}

LineDashedMaterial.prototype = Object.create( LineBasicMaterial.prototype );
LineDashedMaterial.prototype.constructor = LineDashedMaterial;

LineDashedMaterial.prototype.isLineDashedMaterial = true;

LineDashedMaterial.prototype.copy = function ( source ) {

    LineBasicMaterial.prototype.copy.call( this, source );

    this.scale = source.scale;
    this.dashSize = source.dashSize;
    this.gapSize = source.gapSize;

    return this;

};


export { LineDashedMaterial };

ES2015+. Mismo código, pero es2015+ con babel-plugin-transform-class-properties :

import { LineBasicMaterial } from './LineBasicMaterial';
import { Color } from '../math/Color';

export class LineDashedMaterial extends LineBasicMaterial {
  type = 'LineDashedMaterial';

  scale = 1;
  dashSize = 3;
  gapSize = 1;
  isLineDashedMaterial = true;

  constructor(parameters) {
    super();
    this.setValues( parameters );
  }

  copy(source) {
    super.copy(source);

    this.scale = source.scale;
    this.dashSize = source.dashSize;
    this.gapSize = source.gapSize;

    return this;
  }
}

Características de ES6 que simplificarían el código three.js:

Estoy a favor de pasar a ES2015+, solo necesitamos encontrar una manera de generar un código similar al que tenemos actualmente, para que el rendimiento sea el mismo en todos los casos.

Tengo una pregunta en el contexto de las clases. ¿Cómo transferiríamos métodos como Vector3.unproject a la sintaxis de la clase? El método en realidad usa un cierre para crear un nuevo alcance. Este es un mecanismo importante que mantiene la cantidad de creaciones de objetos lo más baja posible.

¿Necesitamos Object.assign en estos casos?

@Mugen87 @mrdoob Alguna información interesante sobre el rendimiento de es6. Especialmente en Object.assign :
image
De este artículo

¿Cómo transferiríamos métodos como Vector3.unproject a la sintaxis de la clase? El método en realidad usa un cierre para crear un nuevo alcance.

@ Mugen87 ¿No pueden ser simplemente objetos de ámbito de módulo no exportados? Algo como esto;

const tempMatrix = new Matrix();    

export default class Vector3{
    unproject() {
        // uses tempMatrix
    }
}

Ah sí, creo que esto debería funcionar 😊

@mrdoob ¡Guau! Parece que ya funciona. ¿No podemos hacer una rama, transformar algunas clases a es6 y ver cómo se compila?


@satori99 Como idea de cómo mantener tempMatrix dentro del código Vector3 para evitar problemas con los globales:

export default class Vector3 {
    static tempMatrix = new Matrix();

    unproject() {
        // uses Vector3.tempMatrix
    }
}

@mrdoob ¡Guau! Parece que ya funciona. ¿No podemos hacer una rama, transformar algunas clases a es6 y ver cómo se compila?

¡Me parece bien! Actualmente me estoy enfocando en WebVR, por lo que tendrá que ser alguien más que yo.

@ sasha240100 El beneficio de usar vars con ámbito de módulo es que permanecen ocultos del código de usuario normal, lo que parece apropiado para las variables temporales.

No me importa el enfoque pitonístico "Todos somos adultos aquí" con respecto a las variables privadas, pero las variables temporales realmente no deberían contaminar el espacio de nombres innecesariamente.

Además, sería bueno que aquellos de nosotros que hemos habilitado la compatibilidad con módulos nativos en nuestros navegadores pudiéramos cargar los archivos src directamente. Esta es una forma mucho más agradable de desarrollar, sin necesidad de observadores y transpilando después de cada edición. Usar propiedades de clase significa que esto no es posible ya que no son parte de la especificación de clase actual.

Disculpas por entrometerme. Probablemente deberíamos cambiar el título del problema a algo como "Evaluar clases de ES6", ya que ahora el hilo ha cambiado a algo completamente diferente.

¿Por qué cambiar el patrón @Mugen87 @satori99 ?

method =(()=>{ 
    const vec3forThisScope =...; 
    return (arg)=>{...}
})()

¿Por qué no probar mecanografiado? Se puede compilar en otras versiones de js.

TypeScript realmente sería una excelente opción para pensar porque es un transpiler + verificador de tipos y un superconjunto de JavaScript, por lo que es fácil mover una base de código a archivos .ts y refactorizar gradualmente a ES6 con verificación de tipos.

Puede sonar aterrador si nunca ha usado TypeScript, pero en realidad no es una gran curva de aprendizaje y sería un pequeño precio a pagar por los beneficios que traería. La comunidad de TypeScript estaría encantada de ayudar con esta transición y crear pruebas de rendimiento con la biblioteca actual para asegurarse de que no se rebaje.

Algunos artículos útiles:

Para citar al desarrollador central Anders Hejlsberg, TypeScript nació en respuesta a las quejas de los clientes y equipos internos de que JavaScript no se prestaba bien a aplicaciones grandes.

El objetivo era "fortalecer JavaScript con cosas como clases, módulos y escritura estática", sin sacrificar la ventaja de ser de estándares abiertos y multiplataforma; el resultado fue un "lenguaje para el desarrollo de javascript a escala de aplicación", creado como un superconjunto del lenguaje.

Hasta que los navegadores puedan ejecutar TypeScript de forma nativa, prefiero seguir usando JavaScript.

@mrdoob

No puedo ver eso como una razón válida para no usar TypeScript únicamente por la razón por la que no se puede ejecutar directamente en el navegador. No querrá que se ejecute en el navegador debido a todas las líneas adicionales de código que están destinadas solo para verificar el tiempo de compilación. Actualmente no es un lenguaje de verificación de tiempo de ejecución. Entonces, si alguna vez se usó en el navegador, es muy probable que se elimine todo el código escrito porque afecta el rendimiento y este sería un código JavaScript estándar.

Creo que te estás perdiendo por completo el punto de usar un lenguaje escrito y los beneficios que tiene en el desarrollo en una gran base de código. Todavía estás escribiendo y usando JavaScript, el objetivo de TypeScript es que es un superconjunto de JavaScript. Usted escribe JavaScript con tipos, que se compila en JavaScript en la versión de destino de ECMAScript especificada, que se puede configurar en las opciones del compilador, los valores permitidos son 'es3', 'es5', 'es2015', 'es2016', 'es2017' o ' es el siguiente'.

Debido a que Typescript es JavaScript, hace posible migrar progresivamente sin tener un dolor de cabeza masivo de refactorizar todo a la vez. Puede ser hecho y mejorado gradualmente por la comunidad. No es más trabajo que lo que se discute aquí con la refactorización para usar las clases de ES6. Esa es la única razón por la que lo menciono aquí en lugar de abrir un nuevo número.

Consulte los enlaces de juegos de TypeScript a continuación para obtener excelentes ejemplos:

@jojordanbrown

¿Puede pensar en alguien que posiblemente no esté de acuerdo con usted acerca de que el mecanografiado es la mejor solución para este problema en particular?

Si escribe typescript vs en Google, aparecerán algunos términos, uno de ellos es Flujo. Buscar eso parece producir una serie de artículos en los que las personas debaten los pros y los contras de estos dos.

Ningún tipo parece más un compromiso que elegir uno de estos.

Guarde Typescript para proyectos que son más complicados que el resultado que crean, especialmente marcos frontend que podrían haberse implementado en HTML en primer lugar. Mi punto original era deshacerme de la enfermedad de JavaScript, no empeorarla. JavaScript es un lenguaje simple, casi de juguete, que a veces se usa para resultados complejos como three.js. El texto mecanografiado no tiene sentido.

El 6 de septiembre de 2017 a la 1:55 p. m., Joe [email protected] escribió:

@mrdoob

No puedo ver eso como una razón válida para no usar TypeScript únicamente por la razón por la que no se puede ejecutar directamente en el navegador. No querrá que se ejecute en el navegador debido a todas las líneas adicionales de código que están destinadas solo para verificar el tiempo de compilación. Actualmente no es un lenguaje de verificación de tiempo de ejecución. Entonces, si alguna vez se usó en el navegador, es muy probable que se elimine todo el código escrito porque afecta el rendimiento y este sería un código JavaScript estándar.

Creo que te estás perdiendo por completo el punto de usar un lenguaje escrito y los beneficios que tiene en el desarrollo en una gran base de código. Todavía estás escribiendo y usando JavaScript, el objetivo de TypeScript es que es un superconjunto de JavaScript. Usted escribe JavaScript con tipos, que se compila en JavaScript en la versión de destino de ECMAScript especificada, que se puede configurar en las opciones del compilador, los valores permitidos son 'es3', 'es5', 'es2015', 'es2016', 'es2017' o ' es el siguiente'.

Debido a que Typescript es JavaScript, hace posible migrar progresivamente sin tener un dolor de cabeza masivo de refactorizar todo a la vez. Puede ser hecho y mejorado gradualmente por la comunidad. No es más trabajo que lo que se discute aquí con la refactorización para usar las clases de ES6. Esa es la única razón por la que lo menciono aquí en lugar de abrir un nuevo número.

Consulte los enlaces de juegos de TypeScript para ver ejemplos:

Ejemplo clásico de JavaScript
Ejemplo de adición de tipos
Adición de tipos con error Ejemplo
Ejemplo de uso de clases
Uso de clases con error Ejemplo

Usted está recibiendo esto porque usted fue el autor del hilo.
Responda a este correo electrónico directamente, véalo en GitHub o silencie el hilo.

^ Estaría bien incluso con el patrón monstruoso, siempre que sea consistente.

@joejordanbrown suena como si estuvieras enamorado del texto mecanografiado. siéntete libre de bifurcar el proyecto y portarlo a mecanografiado. tres.ts! 🙌

@pailhead

Eso es una cuestión de elección, estoy seguro de que muchos estarán de acuerdo y en desacuerdo, ¡eso es normal, aunque correcto! Siempre vas a ver "esto contra aquello", "lo mío es mejor que lo tuyo". Entiendo que cada uno tiene sus propios beneficios. Se trata de sopesar las opciones disponibles y ver si pueden beneficiar al proyecto. Las comparaciones son algo bueno, impulsa los proyectos más allá.

Mencionas Flow, los problemas que veo con eso son:

  • La licencia de flujo es BSD 3-cláusula " Facebook BSD + Licencia de patentes ", Apache Software Foundation prohibió el uso de esta licencia en nuevos proyectos. Puedes leer más detalles aquí .

  • Falta soporte IDE en comparación con TypeScript.

  • La base de usuarios es pequeña en comparación con TypeScript,

  • Las tipificaciones disponibles para las bibliotecas públicas están incompletas, TypeScript tiene muchas tipificaciones bien mantenidas.

  • La documentación y los recursos son difíciles de encontrar y son vagos en comparación con TypeScript; encontrará excelente documentación, libros, videos y muchos otros recursos de aprendizaje electrónico.

  • Flow usa archivos .js que están marcados con // @flow , esto puede ser confuso porque ves la extensión .js , así que espera JavaScript pero, de hecho, es FlowType. Donde TypeScript usa su propia extensión .ts . Esto también le permite tener los archivos de salida de TypeScript y JavaScript con nombres idénticos en el mismo directorio, lo cual es ideal para un proyecto pequeño, obviamente, ese no sería el caso en un proyecto grande porque estaría usando una compilación sistema para gestionar el proceso de construcción.

Incluso Google está respaldando a TypeScript a lo grande, lo que demuestra la confianza que tienen en TypeScript. Lee el post aquí o aquí .

TypeScript se ha permitido para el desarrollo de clientes sin restricciones a partir de marzo de 2017. TypeScript y Angular en TypeScript se utilizan en Google Analytics, Firebase y Google Cloud Platform y herramientas internas críticas como seguimiento de errores, revisiones de empleados y aprobación de productos y herramientas de lanzamiento.

Solo pensé en abrir la discusión sobre el uso de un lenguaje escrito y ver qué piensan los demás sobre la idea. Sin embargo, parece que @mrdoob está totalmente en contra de discutir la idea.


@arctwelve
No veo cómo este proyecto no es complicado y cómo el uso de un lenguaje escrito lo afectaría negativamente.


@mrdoob
En absoluto, solo puedo ver los beneficios que podría tener, especialmente si se crea una nueva rama para actualizar a las clases ES6. Creo que responder con crear tu propia bifurcación llamada tres.ts es simplemente una tontería. Eso está realmente en contra de las buenas prácticas de OSS si todos simplemente bifurcaron proyectos de OSS y modificaron su propio código fuente en lugar de enfocarse en el proyecto 1 y hacerlo lo mejor posible. Terminaría con un software realmente pobre o comunidades que se dividirían y se enfocarían en el proyecto que prefieren por cualquier razón. ¿Por qué no puedes tener una discusión abierta sobre los pros y los contras?

No es por jugar al abogado del diablo, pero parece que lo hizo.

tener una discusión abierta

fue muy corto :)

Comparto un punto de vista similar, es una biblioteca JS y JS está estandarizado. No puede equivocarse al elegir JS para una biblioteca JS, mientras que puede hacerlo si elige otra cosa. Acabo de tomar Flow como una de las alternativas a mecanografiado, no sé si hay otras.

De todos modos, parece que realmente nos salimos del tema.

Mugen87 cambió el título de
Eliminar la enfermedad de JavaScript para evaluar las clases de ES6

El título original se refería (según tengo entendido) a la falta de consistencia en el estilo. En particular, usando Object.assign() en algunos lugares y otro patrón en otros.
Si tuviera que evaluar algo aquí, sería el título actual del problema. ¿Por qué se eleva el tema de la consistencia a una discusión sobre el uso de un nuevo lenguaje?

Me imagino que tanto con TypeScript como con Es6, el código debería ser bastante consistente.

Abordaría este problema actualizando esta página:

https://github.com/mrdoob/three.js/wiki/Mr.doob's-Code-Style%E2%84%A2

y agregando:

A) "... usar Object.assign ..."
B) "... no use Object.assign"

Un estilo en toda la biblioteca. No hay necesidad de cambiarlo.

El fiel estilo de dos líneas todavía en, por ejemplo, las clases de Materiales es mucho más claro y limpio.

Está en la primera publicación.

Yo sugiero:

  1. edite el título para reflejar esta oración, hable sobre tener un estilo en toda la biblioteca, edite la guía de estilo, etc.
  2. inicie una nueva discusión titulada "evaluar clases de es6", donde se evaluarían las clases de es6
  3. iniciar una nueva discusión titulada "evaluar tener tres escritos en un idioma mecanografiado", donde se discutiría el mecanografiado y demás

De todos modos, parece que realmente nos salimos del tema.

Por supuesto. @joejordanbrown siéntase libre de crear un nuevo tema para hablar sobre TypeScript.

Por cierto, también es una mala práctica de OSS ignorar conversaciones anteriores... https://github.com/mrdoob/three.js/issues/341#issuecomment -47000692

Volviendo al tema. Pensé que ya habíamos resuelto este problema.

https://github.com/mrdoob/tres.js/issues/11552#issuecomment-319449068

Solo necesitamos a alguien que lo pruebe.

Ok entonces... antes que nada

Primer patrón (el mejor IMO):

function MyClass() {...}

MyClass.prototype = Object.assign( Object.create( MyClassToInherit.prototype ), {

    constructor: MyClass,

    prop1: 'something',

    method1: function someFunction() { .. },

    ...

});

El segundo patrón:

function MyClass() {...}

MyClass.prototype = Object.create( MyClassToInherit.prototype );

MyClass.prototype.constructor = PointLight;

MyClass.prototype.prop1 = 'something';

MyClass.prototype.method1 = function someFunction() { .. };

...

@arctwelve Este patrón se introdujo por muchas razones. ¡Esto no es masturbarse!

En primer lugar, permite una lectura clara sobre la herencia del objeto. El Object.assign está claramente aquí sobre la herencia del objeto. Entonces no puede perder el objeto heredado en muchas y muchas líneas de MyClass.prototype .
En segundo lugar, en caso de herencia múltiple, esto también es mucho más claro.
Tercero, el constructor de la clase es legible y no se pierde en muchas líneas como el primer punto.
Cuarto, esto permite agrupar propiedades y métodos en la misma ubicación (entre paréntesis), lo cual es mucho más claro cuando tiene 3, 4, 5... etc clases en el mismo archivo.
En quinto lugar, este patrón permite verificar la copia correcta de algunas propiedades "heredadas".

Finalmente ( @looeee ), esto también es para el rendimiento. La primera versión está más optimizada cuando se produce el análisis de archivos, en lugar de llamadas múltiples y múltiples al prototipo.

De todos modos !

¡Hoy en día, deberíamos pasar a la sintaxis de ES6!

@mrdoob

¡Me parece bien! Actualmente me estoy enfocando en WebVR, por lo que tendrá que ser alguien más que yo.
Solo necesitamos a alguien que lo pruebe.

¿Crearías una rama es6? ¿O es por nuestra cuenta?

La primera versión está más optimizada cuando se produce el análisis de archivos, en lugar de llamadas múltiples y múltiples al prototipo.

¿Está usted seguro de eso? Esperaría que Object.Assign fuera más lento, en todo caso. Pero en cualquier caso, dudo que sea una sobrecarga de rendimiento suficiente de la que preocuparse.

Absolutamente: https://jsperf.com/inline-prototype-vs-assign-prototype/1

Bajo la versión de Chrome 61.0.3163.100 (Build officiel) (64 bits) El prototipo asignado es alrededor de un 60% más rápido

Interesante. Gracias por hacer la prueba.

Sin embargo, ese resultado no es válido para todos los navegadores. En Firefox son casi iguales ( Object.Assign ~3% más rápidos), mientras que en Edge Object.Assign es ~33% más lento .

Pero en cualquier caso, todavía no creo que esto sea relevante como argumento para determinar qué estilo es mejor: incluso el más lento en general (protocolo en línea en Chrome) todavía se ejecuta a> 180,000 operaciones por segundo, y tal vez haya un par de miles de estas configuraciones hechas en el código. Así que estamos hablando de una diferencia de unos pocos milisegundos aquí, probablemente.

Para mí, el estilo Object.Assign es más limpio y fácil de leer, y ese es el principal argumento a favor.

Sí, se trata de unos pocos milisegundos por archivo y solo cuando el motor javascript analiza el archivo por primera vez ... pero para una biblioteca grande como threejs, la ganancia podría ser razonablemente de alrededor de 200 milisegundos en la carga de la página.
¡No olvide el límite de 3scd para el usuario principal que no puede esperar más!

Estoy tratando de hacer un proyecto Angular con threejs y siempre parece que estoy pirateando cada parte de threejs.
En primer lugar, es la sintaxis es5 con TRES constantes que deben existir, por ejemplo, si necesito OrbitalControls.
Tenemos tres tipos de js, pero será más conveniente tenerlos en el mismo paquete. Los tipos tienen OrbitalControls, pero no podemos simplemente importar como import { OrbitalControls } from 'three; .
Webpack tiene agitación de árboles, por lo que en el caso de es6 podríamos incluir todo lo que necesitamos dentro de un proyecto y no moverlos a uno separado.
@mrdoob entonces, ¿por qué Typescript es tan malo? Se compilará a ES cualquier versión con mecanografiados de todos modos.
También se usa en muchos otros marcos como React.

@FriOne No estoy seguro de si @mrdoob realmente piensa que Typescript es malo, pero creo que está en contra de discutir Typescript en este tema/hilo porque no es el tema de este hilo. Creo que las clases de ES6 no funcionan contra o para Typescript. Si transforma el código base a ES6, es aún más fácil transferir el código base a Typescript porque su sintaxis es muy similar. Sí, creo que Typescript podría habilitar muchas opciones nuevas. Por ejemplo, podría ayudar a "transpilar" un código más optimizado, ayuda a los nuevos desarrolladores a aprender la biblioteca más rápido, tal vez abra puertas para experimentos en el futuro, por ejemplo: https://github.com/AssemblyScript/assemblyscript. Creo que hay muchas ventajas con Typescript @joejordanbrown describió las ventajas en detalle.

Pero volviendo al tema: creo que adoptar las clases de ES6 sería un paso adelante y, después de eso, podríamos discutir el asunto de Typescript. Así que vamos a hacer un paso después del otro

@tschoartschi , creo que mecanografiado puede ayudar con la migración a clases es6 y otras refactorizaciones. No tengo tanta experiencia en migración, puede que me equivoque.

@FriOne depende 😉, por supuesto, Typescript podría ayudar porque el compilador podría decirle todos sus errores y errores, pero primero tendría que configurar todo el conducto de compilación para trabajar con Typescript. Además, debe evaluar si Typescript es el ajuste correcto o no. Creo que está bien convertir primero a clases ES6 y luego pensar en Typescript.

Hola, somos un grupo de 5 estudiantes de KTH que buscan contribuir a un proyecto de código abierto para un curso y nos gustaría intentar convertir una parte del proyecto a la nueva sintaxis ES6.

Transferí Three.js a TypeScript hace un tiempo (r82) junto con algunos de los ejemplos, como prueba de concepto.

https://github.com/flyover/tres.ts

Los ejemplos tardan un poco en cargarse, ya que la fuente de TypeScript se transpila sobre la marcha. Se cargan tan rápido como los originales cuando se usa el JavaScript transpilado.

Me encantaría ver three.js portado a mecanografiado. Siento que el proyecto necesita urgentemente ser modernizado si quiere resistir el paso del tiempo para las próximas generaciones web. Un día, es posible que incluso lo veamos funcionando con AssemblyScript y ejecutándose en WASM. Si no son tres, entonces algo más seguramente lo hará.

Esto se completa @WestLangley y @mrdoob

@bhouston ¿cuál es la conclusión aquí?

@pkieltyka sí, también creo que TypeScript tendría mucho sentido para una biblioteca como Three.js. Además de todas las ventajas técnicas, también facilitaría el uso de la biblioteca y ayudaría a los novatos a explorar la API. Pero también creo que es importante terminar primero todo el material de ES6 y luego considerar TypeScript. Creo que desde el último JavaScript no es demasiado complicado agregar tipos en forma de TypeScript.

@flyover agradable también ver una prueba de concepto para una versión TypeScript de Three.js. ¿Recibió comentarios de los mantenedores de Three.js?

También admito mecanografiado para three.js. typecirpt es básicamente mejor
la práctica y JavaScript en bruto ya no existe.

El sábado 5 de enero de 2019 a las 4:13 a. m., tschoartschi < [email protected] escribió:

@pkieltyka https://github.com/pkieltyka sí, también creo que TypeScript
tendría mucho sentido para una biblioteca como Three.js. Al lado de todos los
profesionales técnicos también facilitaría el uso de la biblioteca y ayudaría a los novatos
para explorar la API. Pero también creo que es importante terminar todo el ES6
Rellene primero y luego considere TypeScript. creo que de lo ultimo
JavaScript no es demasiado complicado para agregar tipos en forma de TypeScript.

@flyover https://github.com/flyover agradable también ver una prueba de concepto para
una versión TypeScript de Three.js. ¿Recibiste comentarios de los mantenedores?
de Three.js?


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/mrdoob/tres.js/issues/11552#issuecomment-451639995 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AAj6_bkdND7I0_F4AJcBV0DYLpToUIVhks5vAGykgaJpZM4N9vH8
.

@bhouston Estoy de acuerdo en que TypeScript es una gran tecnología, pero no lo expresaría de la forma en que lo hizo. Creo que siempre debemos mantenernos lo más cerca posible de JavaScript sin procesar y agregar las funciones de TypeScript en la parte superior. Dado que TypeScript sigue muy de cerca las especificaciones de JavaScript, TypeScript realmente se lee como ES6 con tipos.

Para una biblioteca como three.js, TypeScript podría ser realmente beneficioso y podría adoptarse gradualmente. Por lo tanto, no necesitaríamos una reescritura "a lo grande", especialmente después de que se hayan terminado todos los refactores de ES6.

Sería interesante saber si la postura de @mrdoob sobre TypeScript cambió. TypeScript parece convertirse en el estándar "de facto" para "JavaScript escrito" (tenga en cuenta que puse mis afirmaciones bajo un apóstrofo ya que no son hechos concretos)

El primer paso debe ser adoptar las características de ES6, especialmente las clases, la función de flecha, 'let' y 'const'.

Una vez que hayamos hecho eso, podemos analizar adecuadamente la compatibilidad con mecanografiado ya que, como señala @roomle-build, es fácil agregar gradualmente características de mecanografiado sobre el código ES6 gradualmente si así lo decidimos.

Hacer ambas cosas a la vez me parece que complicaría demasiado las cosas.

Genial escuchar que TypeScript podría ser una opción en algún momento en el futuro :-) tal vez podríamos reutilizar parte del trabajo realizado por @flyover

Pero estoy totalmente de acuerdo con @looeee en terminar todas las cosas de ES6 primero y luego concentrarme en los siguientes pasos.

terminar todas las cosas ES6

Sería feliz si al menos pudiéramos empezarlo 😅

Un buen paso a mitad de camino para TypeScript sería agregar archivos de tipo junto a cada archivo JavaScript. Por lo tanto, habría ambos:

Vector3.js
Vector3.d.ts

Esto nos brinda todos los beneficios de TypeScript como archivos secundarios.

En este momento hay un archivo @types/tres pero está desactualizado y se mantiene por separado, por lo que siempre estará sin datos.

El principal competidor de Three.JS es Babylong y está completamente mecanografiado y creo que se beneficia de esto.

Pero eliminar @types/three e integrarlo como archivos de definición de tipos de sidecars en Three propiamente dicho sería un excelente primer paso.

También necesitamos integrar todos los ejemplos en /src con algún tipo de agitación del árbol.

En este momento, la estructura del código para Three.JS es tan 2014 y solo un dolor para trabajar.

¿Todos los ejemplos?

Ejemplos/js

El lunes 7 de enero de 2019 a las 10:25 a. m., Dusan Bosnjak < [email protected] escribió:

¿Todos los ejemplos?


Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/mrdoob/tres.js/issues/11552#issuecomment-451970482 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AAj6_Q3Kakb5Qn2DqGbMVvLkW_28cOyaks5vA2b5gaJpZM4N9vH8
.

@bhouston

Un buen paso a mitad de camino para TypeScript sería agregar archivos de tipo junto a cada archivo JavaScript. Por lo tanto, habría ambos:

Vector3.js
Vector3.d.ts

¿Los archivos .d.ts actuarían como archivos .h en c?

¿Los archivos .d.ts actuarían como archivos .h en c?

Esa es una muy buena analogía. Es interesante que alguien ya haya hecho la mayor parte de esto aquí: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/three Por lo tanto, realmente solo tomaría posesión de estos tipos de archivos e los integraría en Three.js. Si lo desea, podemos crear un PR que integre esto en Three.js y lo divida correctamente.

Para mostrar qué tan popular es Typescript, mire cuántos @Types/tres se descargan por semana:

https://www.npmjs.com/package/@types/tres : 63 000 descargas por semana.

¡Impresionante!

Si lo desea, podemos crear un PR que integre esto en Three.js y lo divida correctamente.

Me parece bien 👍

¿Es posible ejecutar una verificación de línea de comandos, similar a eslint, asegurándose de que los archivos de tipo y los archivos fuente .js estén alineados? Si estamos asumiendo la propiedad de los archivos d.ts , sería muy preferible tener alguna forma de verificar periódicamente que coincidan.

Para mostrar qué tan popular es Typescript, mire cuántos @Types/tres se descargan por semana:

https://www.npmjs.com/package/@types/tres : 63 000 descargas por semana.

Atribuiría esto más a la popularidad de Visual Studio Code, porque sucede automáticamente cuando usa Visual Studio Code, a través de su función de Adquisición automática de tipos.
Dicho esto, no se puede ignorar.

@flyover @bunnybones1 @mrdoob @looeee @donmccurdy @bhouston @roomle-build @pkieltyka @FriOne @joejordanbrown ya que todos ustedes parecen estar interesados ​​en TypeScript, quería señalar que creé un nuevo problema relacionado con TypeScript. Creo que tiene sentido mover todas las discusiones de TS allí. Si está interesado, puede encontrarlo aquí: https://github.com/mrdoob/three.js/issues/15545

Estoy dispuesto a dedicar tiempo a migrar a las clases de ES6. Creo que esta será una buena solución puente para algún día admitir Typescript.

El primer paso es convertir algunos de los complementos a ES6.

https://github.com/mrdoob/tres.js/tree/dev/examples/jsm

Los controles, los cargadores y los exportadores son buenos candidatos. ¡Siéntete libre de ayudar!

@mrdoob solo para confirmar, te refieres a convertirlos en módulos ES pero aún no usar otras funciones de ES6, ¿verdad?

Supongo que el proceso de hacer esa conversión es:

  1. Utilice el script modularize.js para convertir el archivo original en un módulo ES.
  2. Limpie los problemas si es necesario.
  3. En algún momento (esta versión o en un futuro cercano) comenzaremos a usar rollup-examples.config.js para convertir los módulos ES en módulos UMD, momento en el cual la versión en examples/js ya no es mantenida por mano.
  4. Una vez que esté estable, podemos considerar otros cambios, como la introducción de características de ES6.

@mrdoob solo para confirmar, te refieres a convertirlos en módulos ES pero aún no usar otras funciones de ES6, ¿verdad?

Sí, lo siento. Debería haber especificado.

@bhouston y yo hemos creado el PR prometido que aporta los archivos *.d.ts para la mayor parte del proyecto Three.JS. https://github.com/mrdoob/tres.js/pull/15597

No puedo esperar a las clases de ES6 y las definiciones de Typescript. Cada vez que trabajo con three.js, tengo que copiar y pegar cientos de líneas de código para volver a implementar una función que se encuentra en un ámbito inaccesible. Realmente no es una forma elegante de trabajar si tienes que optimizar tus escenas. Llevaría el flujo de trabajo a un nuevo nivel para finalmente poder extender y anular funciones.
Por lo tanto, haga que las funciones de clase estén al menos "protegidas" y accesibles sin excepción 🤗

Cada vez que trabajo con three.js, tengo que copiar y pegar cientos de líneas de código para volver a implementar una función que se encuentra en un ámbito inaccesible. ... Por lo tanto, haga que las funciones de clase estén al menos "protegidas" y accesibles sin excepción.

@dionysiusmarquis No estoy seguro de entender lo que quiere decir aquí... ¿los tipos de TS existentes tienen funciones que desea usar incorrectamente marcadas como privadas? ¿O algo sobre las definiciones de clase de estilo de prototipo actuales dificulta el uso en TS? ¿Podrías compartir un ejemplo?

Cada vez que trabajo con three.js, tengo que copiar y pegar cientos de líneas de código para volver a implementar una función que se encuentra en un ámbito inaccesible. ... Por lo tanto, haga que las funciones de clase estén al menos "protegidas" y accesibles sin excepción.

@dionysiusmarquis No estoy seguro de entender lo que quiere decir aquí... ¿los tipos de TS existentes tienen funciones que desea usar incorrectamente marcadas como privadas? ¿O algo sobre las definiciones de clase de estilo de prototipo actuales dificulta el uso en TS? ¿Podrías compartir un ejemplo?

Solo quería implementar un mapa de sombras específico para un escenario específico. Habría ayudado poder anular getDepthMaterial por ejemplo. En este momento, inyecto mi propio WebGLShadowMap en el proceso de compilación con una versión de copiar/pegar que incluye los cambios deseados.
Sería muy bueno si cada clase three.js expusiera todo lo posible. Con mecanografiado, puede marcar fácilmente funciones como private o protected para describir el propósito previsto. Mi ES6 Class/Typescript ShadowMap, por ejemplo, se ve así:

interface MaterialCache {
  [uuid: string]: {[uuid: string]: MeshDepthMaterial}
}

class ShadowMap {
  public enabled: boolean = false
  public autoUpdate: boolean = true
  public needsUpdate: boolean = false
  public type: ShadowMapType

  …

  protected depthMaterials: MeshDepthMaterial[]
  protected materialCache: MaterialCache

  constructor (renderer: WebGLRenderer, objects: WebGLObjects, maxTextureSize: any) {
    …
  }

  protected getDepthMaterial (object: Object3D, material: Material) {
    …
  }
}

export { ShadowMap as WebGLShadowMap }

Se siente como en casa si se le permite modificar las clases de "bajo nivel"

Tengo una pregunta en el contexto de las clases. ¿Cómo transferiríamos métodos como Vector3.unproject a la sintaxis de la clase? El método en realidad usa un cierre para crear un nuevo alcance. Este es un mecanismo importante que mantiene la cantidad de creaciones de objetos lo más baja posible.

¿Necesitamos Object.assign en estos casos?
@Mugen87

Ya puedes hacer cierres con clases. Simplemente no es obvio cómo navegar en ese azúcar sintáctico. Vea mi respuesta en StackOverflow: https://stackoverflow.com/questions/39297258/iife-in-es6-class-literal/56077521#56077521 (Debo ser humilde y admitir que no entiendo completamente cómo/por qué funciona .)

Lo sentimos, pero este código parece un antipatrón y no deberíamos adaptarlo en el proyecto. Existen soluciones adecuadas para la gestión de variables en el ámbito del módulo. Sugiero ir por esta ruta.

@ Mugen87 sí, también creo que deberíamos hacer un buen uso del alcance del módulo. Esto también ayudaría para cosas como sacudir árboles. Esto ya se discutió en muchos otros números como este: https://github.com/mrdoob/three.js/issues/6241#issuecomment -398703521

Lo sentimos, pero este código parece un antipatrón y no deberíamos adaptarlo en el proyecto. Existen soluciones adecuadas para la gestión de variables en el ámbito del módulo. Sugiero ir por esta ruta.

No hay problema. Acabo de mencionar la posibilidad. Si tiene una solución mejor/más limpia en camino, estoy ansioso por verla en acción. El proyecto Three.js (uso, fuente, debates, etc.) ha sido mi principal fuente de conocimiento de JS, por lo que la introducción de nuevos y mejores patrones de programación en Three.js probablemente me beneficie a mí y a mis proyectos también. Nada que lamentar. ;-)

@ Mugen87 ¿Puede explicar un poco por qué considera que los IIFE de clase son un patrón anti, aunque solo sea para que pueda aprender y comprender un poco más? Entiendo que los módulos abarcan las variables de forma inherente, pero eso no es diferente de cómo se construía el núcleo anteriormente. Y con tantas funciones que usan variables de caché, será muy importante asegurarse de que ninguna de las funciones colisione o use variables al mismo tiempo: el alcance de la función hace que esto sea más fácil de administrar y mantener, razón por la cual no veo como un anti-patrón (al menos en comparación con arrojar todas las variables de caché en el alcance del módulo).

¿Puede explicar un poco por qué considera que los IIFE de clase son un patrón anti

No usaría un enfoque que potencialmente impida la sacudida de árboles como se menciona aquí: https://github.com/mrdoob/three.js/pull/14695. Además, creo que todo el patrón parece un truco. El uso de enfoques menos "elegantes" generalmente funciona mejor. Evitar cierres innecesarios también debería mejorar el rendimiento de la ejecución del código en general (no puedo probar esto con una referencia, pero lo escuché en una charla hace algún tiempo).

Y con tantas funciones que usan variables de caché, será muy importante asegurarse de que ninguna de las funciones colisione o use variables al mismo tiempo.

Los IIFE se utilizan principalmente en las clases de matemáticas. Dado que tenemos una buena cantidad de cobertura de prueba allí ( @gero3 hizo un gran trabajo últimamente al agregar más pruebas unitarias), debería ser más fácil eliminarlas de manera sólida.

Está bien eliminar los IIFE. Creo que soy responsable de ello en 2013. Fue para deshacerse de un patrón variable estático que era difícil de mantener. Se hizo en este PR:

https://github.com/mrdoob/tres.js/pull/2941

https://github.com/mrdoob/tres.js/issues/2936

Y discutido incluso antes aquí:

https://github.com/mrdoob/tres.js/pull/2920#issuecomment-12217793

Dato interesante, cuando los pusimos, no hubo una diferencia en el rendimiento del código.

Supongo que el proceso de hacer esa conversión es:

  1. Utilice el script modularize.js para convertir el archivo original en un módulo ES.
  2. Limpie los problemas si es necesario.
  3. En algún momento (esta versión o en un futuro cercano) comenzaremos a usar rollup-examples.config.js para convertir los módulos ES en módulos UMD, momento en el que la versión en examples/js ya no se mantiene mano.
  4. Una vez que esté estable, podemos considerar otros cambios, como la introducción de características de ES6.

Oye. podría haberlo perdido, pero ¿cuáles fueron nuestros pasos incrementales hacia las clases?

  1. [x] Utilice el script modularize.js para convertir el archivo original en un módulo ES.
  2. [x] Limpiar problemas si es necesario.
  3. [ ] En algún momento (esta versión o en un futuro cercano) comenzaremos a usar rollup-examples.config.js para convertir los módulos ES en módulos UMD, momento en el que la versión en Examples/js ya no se mantiene mano.
  4. [ ] Una vez que esté estable, podemos considerar otros cambios, como la introducción de características de ES6.

En los pasos anteriores, esencialmente hemos terminado los pasos (1) y (2).

Paso (3) ya no lo haremos de esa manera, sino que dejaremos de usar y eliminaremos la carpeta examples/js en algún momento (ver https://github.com/mrdoob/three.js/pull/18749) .

Creo que eso significa que el paso (4), la introducción de clases ES6 a examples/jsm solo se puede realizar (por ahora) en los pocos ejemplos que no se generan a partir de las versiones fuente de examples/js . Una vez que se elimine examples/js , podemos hacer el resto.

^ Pero podría estar leyendo demasiado entre líneas aquí, ¿tal vez @Mugen87 o @mrdoob puedan confirmarlo?

En mi opinión, el proyecto debe centrarse en la desaprobación y eliminación de examples/js para lograr una base de código de solo módulo. En el siguiente paso, recomendaría continuar con la migración de clases. Comenzando con los ejemplos y luego migrando el núcleo.

Perfecto. gracias. echará un vistazo más de cerca a esas formas

Reenviado de un número cerrado.
Hola,

Quería crear este problema para intentar descifrar los pensamientos de todos sobre cómo nos gustaría avanzar con la migración de clases.

Mi resumen rápido de lo que he encontrado hasta ahora:

  • Deberíamos desaprobar la carpeta de ejemplos antes de hacer cualquier otra cosa.
  • Hay partes de src/ que no están extendidas por ninguno de los ejemplos que podrían convertirse
  • Con algunos cambios en la secuencia de comandos modularize.js, podríamos comenzar con ejemplos/js/, que genera las secuencias de comandos de ejemplos/jsm correspondientes.

¿Me he perdido algo?

Deberíamos desaprobar la carpeta de ejemplos antes de hacer cualquier otra cosa.

No estoy seguro de quién es el responsable del siguiente paso específico en la carpeta examples/js . A menos que podamos articular ese plan, preferiría que esto no bloqueara la conversión de cosas a clases ES. Por esa razón, no estoy de acuerdo con https://github.com/mrdoob/three.js/issues/11552#issuecomment -592768708. 🙂

además de eso, parece que solo estamos esperando que se establezca una fecha

Además, como parte de una pequeña revisión que hice, encontré este comentario sobre cómo se podrían introducir otras características de ES2015 a través del proceso de compilación actual. Incluso se da un ejemplo .

editar: aquí hay una esencia de otro ejemplo rápido

@DefinitelyMaybe Tengo algo de tiempo y me encantaría ayudar. ¿Puedo tomar algunos artículos de la lista dependencies.json ?

@DefinitelyMaybe ¿Cuál es la mejor manera de lidiar con la herencia de un ancestro profundo como Object3D ? Por ejemplo, me encontré con una rotura al convertir src/audio/AudioListener.js :

[ROLLUP] bundles src/Three.js → build/three.js...
[ROLLUP] (!) Error when using sourcemap for reporting an error: Can't resolve original location of error.
[ROLLUP] src/audio/AudioListener.js: (137:1)
[ROLLUP] [!] Error: 'return' outside of function
[ROLLUP] src/audio/AudioListener.js (137:1)
[ROLLUP] 135:   };
[ROLLUP] 136: 
[ROLLUP] 137:   return AudioListener;
[ROLLUP]        ^
[ROLLUP] 138: }(Object3D));
[ROLLUP] Error: 'return' outside of function

íbamos a hacer una nota en la parte superior del archivo sobre cualquier problema que encontráramos, si no recuerdo mal.

Entendí mal lo que estaba sucediendo con AudioListener... Después de algunas depuraciones, creo que hay un problema de coincidencia en la transformación bubleCleanup . Consulte https://github.com/mrdoob/three.js/pull/19934#issuecomment -667411997 para obtener más información. Me encontré con esto con algunas clases diferentes, por lo que probablemente tendremos que solucionarlo antes de continuar.

este será el caso de algunos de los archivos, pero no de todos. Estábamos anticipando tal problema.

Para aquellos que siguen, lea rápidamente la discusión aquí .

Mientras tanto, apuesta por src/loaders !

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