Three.js: Migración a Clases ES6

Creado en 2 ago. 2020  ·  88Comentarios  ·  Fuente: mrdoob/three.js

Hola a todos,

Consideré apropiado crear un nuevo problema (en lugar de continuar con el n.º 11552) para ayudar aún más a todos a realizar un seguimiento y actualizarse sobre los problemas y el progreso en torno al cambio a las clases de ES6. Esto también debería ser útil para el documento de lanzamiento.

Para aquellos que deseen ayudar, revisen la lista a continuación y háganos saber en qué les gustaría trabajar. Se prefiere un PR por clase, sin embargo, algunas carpetas se pueden hacer todas a la vez . Si un archivo en particular no se puede convertir, haga una nota en la parte superior del archivo o envíeme un ping desde su PR y lo anotaré a continuación.

Notas:

  • por Class.prototype.is** usa Object.defineProperty( this, 'is**', { value: true } );
  • los campos de clase también están disponibles si corresponde #20395
  • new this.contructor() != new Foo() ... discusión relacionada .
  • Marcará después de fusionarse y completarse.

Parte 1: origen

  • [ ] origen

    • [ ] animación (#19964, #20014, #20016)

    • [ ] pistas ( #20013 )

    • [x] audio (#19975, #20003)

    • [ ] cámaras ( #20102 )

    • [ ] núcleo (#19976, #19977, #19978, #19984, #20008)

    • [x] extras ( #19979 )

    • [ ] núcleo ( #20656 )



      • Curva omitida como extendida dentro de los ejemplos



    • [ ] curvas ( #20140 )

    • [ ] objetos ( )



      • Usado en examples/objects/MarchingCubes.js , tendrá que esperar. referencia #20030



    • [x] geometrías ( #19994 )

    • [x] ayudantes ( #19996 )

    • [ ] luces ( #20018 )

    • [ ] cargadores ( #19985 )

    • El cargador base no se puede hacer todavía

    • [ ] materiales ( #20100 )

    • [x] matemática ( #19980, #19997, #20076, #20089)

    • Los interpoladores esperarán hasta que abordemos examples/js

    • [ ] objetos (#20658 )

    • [ ] renderizadores ( #20101 )

    • [ ] webgl (#20070)

    • [ ] webxr (#20038)

    • [x] escenas ( #20007 )

    • [ ] texturas ( #20009 )

Todavía no estamos listos para la Parte 2. Se necesita discusión.

Parte 2: ejemplos

  • [ ] ejemplos

    • [ ] animación

    • [ ] cámaras

    • [ ] control S

    • [ ] curvas

    • [ ] efectos

    • [ ] exportadores

    • [ ] geometrías

    • [ ] interactivo

    • [ ] luces

    • [ ] líneas

    • [ ] cargadores

    • [ ] Matemáticas

    • [ ] varios

    • [ ] modificadores

    • [ ] objetos

    • [ ] Postprocesamiento

    • [ ] renderizadores

    • [ ] sombreadores

Parte 3: Suelta los cabos y ordena

  • [ ] src/núcleo/Objeto3D
    ...

Comentario más útil

@ianpurvis genial! ¿Estás usando rollup, verdad? ¿podrías compartir tu configuración?

@mrdoob Finalmente pude hacer algunas pruebas. Personalmente uso webpack, así que hice algunas pruebas con él, mi configuración es esta si alguien está interesado .

Probé este código

import * as THREE from 'three'

console.log(THREE.WebGLRenderer)

0.119.1

0 119 1

0.120.1

0 120 1

Así que algo está siendo sacudido, ¡genial!

Mirándolo más, parece que la clase AudioListener no está en el paquete, ¡buenas noticias!

Screenshot 2020-09-01 at 16 49 22

Screenshot 2020-09-01 at 16 50 07

Webpack también elimina automáticamente las variables no utilizadas señaladas por @ianpurvis.


Después de esto, decidí probar métodos estáticos definidos fuera de la clase.

Screenshot 2020-09-01 at 16 50 37

y desafortunadamente, esto hace que la clase no se pueda sacudir en forma de árbol

Screenshot 2020-09-01 at 16 51 04


Después de investigar un poco más, noté que las clases de geometría como DodecahedronGeometry , que no se usaban en ninguna parte, todavía estaban en el paquete.

Screenshot 2020-09-01 at 16 51 29

Screenshot 2020-09-01 at 16 52 08

Más tarde descubrí que esto se debía a este objeto Geometries en el paquete three.module.js

Screenshot 2020-09-01 at 17 18 32

Que se genera automáticamente al usar patrones como este en el ObjectLoader . Esto probablemente desaparecerá cuando hagamos ObjectLoader una clase, y src/geometries se podrá sacudir.

Todos 88 comentarios

Llamaré a dibs en el resto de la carpeta de audio 🔈

hola @mrdoob , ¿podría aclarar cómo desea que manejemos los scripts dentro de la carpeta de ejemplos?

Me gusta #19989 yendo directamente a la conversión, pero me doy cuenta de que al hacerlo, el utils/modularize.js ya no se puede usar en la carpeta examples/js sin sobrescribir ese trabajo. ¿Esto marca el final de nosotros manteniendo el examples/js y el comienzo de solo examples/jsm ?

editar: ver comentario

¿Podría trabajar en el resto de la carpeta de matemáticas?

¿Podría trabajar en el resto de la carpeta de matemáticas?

Estoy a favor de que le des una oportunidad. Recuerdo que lo intenté hace un tiempo, pero @ Mugen87 terminó regañandome por eso. El resumen rápido de eso fue una prueba sobre la marcha porque convertir toda la carpeta de una sola vez podría estar preparándose para un viaje difícil. Un parcial, o incluso archivo por archivo, sería bienvenido, estoy seguro.

@DefinitelyMaybe Veré qué más se puede migrar bajo src/animation/

bonito. Creo que esa carpeta está casi terminada. ¿Podrían quedar solo src/core/Object3D.js y src/core/BufferGeometry.js ?

¿Podrían quedar solo src/core/Object3D.js y src/core/BufferGeometry.js ?

Sí, hay muchas clases de ES5 que dependen de Object3D y BufferGeometry .

Dispara, ha habido un progreso increíble en esto 🎉

Voy a llamar a dibs en src/lights . Abrió src/extras y src/renderers en la lista anterior, resulta que hay un par de carpetas en cada una para trabajar.

Oigan todos,

¿Qué estábamos haciendo con respecto a este patrón?

foo.prototype = Object.assign( Object.create( bar.prototype ), {
    ...
    isDirectionalLight: true,
    ...
} );

es ahora:

class foo extends bar {
  static isDirectionalLight = true;
  constructor(  ) {
    ...
  }
}

o

class foo extends bar {
  constructor(  ) {
    this.isDirectionalLight = true;
  }
}

Actualmente, he estado haciendo el segundo, pero al verlo, diría que la intención de esto podría haber estado más cerca del primero.

¿Alguien sabe qué estaba usando estas variables en primer lugar?

class foo extends bar {
  constructor(  ) {
    this.isDirectionalLight = true;
  }
}

☝️ Esto es correcto. isDirectionalLight es un buen ejemplo, se usa así:

$ git grep 'isDirectionalLight\b' src/ examples/js ':!*.ts'
examples/js/exporters/GLTFExporter.js:                  if ( light.isDirectionalLight ) {
examples/js/exporters/GLTFExporter.js:                  } else if ( object.isDirectionalLight || object.isPointLight || object.isSpotLight ) {
examples/js/renderers/SVGRenderer.js:                   } else if ( light.isDirectionalLight ) {
examples/js/renderers/SVGRenderer.js:                   if ( light.isDirectionalLight ) {
src/lights/DirectionalLight.js: isDirectionalLight: true,
src/renderers/webgl/WebGLLights.js:                     } else if ( light.isDirectionalLight ) {

Dicho esto, podría haber mejoras en el rendimiento al retener algunas propiedades del prototipo...

class foo extends bar {
}
foo.prototype.baz = heavyThing;

Tal vez podamos revisar los de PR caso por caso.

Intentaré src/renderers/webgl 👍 👍

buena suerte, diviértete. ese tiene un poco de eso

Hola a todos, tengo src/renderers/webgl convertidos. Fue loco. Seguiré revisando todo y esperaré al #20039 antes de comenzar a promocionar las relaciones públicas.

👍
esperándolo

Me di cuenta de que @yomotsu usó captadores de solo lectura para las propiedades is* en las relaciones públicas matemáticas... ¡Quizás eso sea lo mejor!

class foo extends bar {
  get isDirectionalLight() {
    return true;
  }
}

mmm puede ser. Sé que otros han intentado en lugares hacer que las variables no se puedan modificar. Esto me parece un patrón bastante decente.

caso de demostración rápido de jsfiddle

Parece que este es el camino a seguir:

foo.prototype.isDirectionalLight = true;

voy a investigar src/objects . Veré hasta dónde puedo llegar sin romper cosas.

La carpeta de matemáticas se acaba de completar.
( Las clases interpoladas están excluidas).

oigan todos,
Voy a dejar de trabajar en src/objects , alguien más es más que bienvenido a recogerlo mientras tanto.

¡Oye, buen trabajo con estos chicos! 💪

Solo un problema, foo.prototype.isDirectionalLight = true; aún no permite sacudir árboles, ya que la clase se modifica en su lugar.
Además, en este punto, recomendaría enfáticamente no volver a tocar el prototipo, ya que ahora estamos usando clases y el prototipo se puede abstraer.

¿Qué pasa con este patrón? A mí me parece lo más explícito.

constructor( x = 0, y = 0, z = 0 ) {

  Object.defineProperty( this, 'isVector3', {
    value: true,
    enumerable: false,
    writable: false,
    configurable: false,
  } );

También existe la versión corta, que hace lo mismo pero es un poco más implícita.

constructor( x = 0, y = 0, z = 0 ) {

  Object.defineProperty( this, 'isVector3', { value: true } );

@marcofugaro me parece bien la versión corta 👍

Ok, hice relaciones públicas.

Además, acabo de notar que no podemos usar campos de clase porque estamos bloqueados por este PR .

Puedo actualizar la canalización de compilación para usar el @rollup/plugin-babel más popular

Puedo actualizar la canalización de compilación para usar el @rollup/plugin-babel más popular
y solucionen ese problema si quieren.

Sí, sería genial si pudieras hacer una PR 🙏

@marcofugaro , @mrdoob ¡bien! sí, por favor

Hola a todos, aviso rápido de que actualicé #20014 con Object.defineProperty y también arreglé la subclasificación de AnimationClip . Si alguien tiene tiempo para revisarlo, agradecería el extra 👀 🙇 🙇

Bueno. Ahora que r120 está disponible... ¿alguien podría verificar que las cosas se están sacudiendo correctamente?

Parece que funciona un poco para mí, pero un poco.
Ya no veo ArrowHelper en mi archivo de paquete con webpack. pero todavía existen muchos códigos innecesarios 😢

¿Qué tal el tamaño del paquete? antes y después de

Hola a todos, tuve una idea y puse una herramienta llamada shakediff . Puedes ejecutarlo así:

$ shakediff builds/three.module.js Color

Eso generará un pequeño módulo importando Color , lo empaquetará con tres y luego creará una diferencia de tres a partir de los metadatos del resumen. Puede trabajar con la diferencia detallada o simplemente canalizarla a diffstat para obtener el nivel alto:

$ shakediff build/three.module.js Color | diffstat 
 three.module.js | 2878 --------------------------------------------------------
 1 file changed, 1 insertion(+), 2877 deletions(-)

En este momento no hay ningún paquete, pero puedes instalarlo desde mi repositorio si quieres probarlo. Comentarios apreciados! ✌️

npm -g i ianpurvis/shakediff.git

hola @mrdoob , ¿podría aclarar cómo desea que manejemos los scripts dentro de la carpeta de ejemplos?
Me gusta #19989 ir directamente a la conversión, pero me doy cuenta de que al hacerlo, utils/modularize.js ya no se puede usar en la carpeta de ejemplos/js sin sobrescribir ese trabajo. ¿Esto marca el final de nosotros manteniendo los ejemplos/js y el comienzo de solo ejemplos/jsm?

¿Cuál es el veredicto sobre este @mrdoob? ¿Tendría sentido hacer de jsm la fuente de la verdad para que podamos convertir ejemplos en clases ES6? ¿Quizás podamos hacer utils/demodularize.js para admitir la conversión en la otra dirección?

La carpeta examples/js se eliminará en diciembre de 2020. Hasta entonces, debemos dejar la carpeta como está, sin actualizar su contenido, o los archivos examples/jsm generados a partir de su contenido, a ES6 Classes. Después de esa fecha, los archivos examples/jsm se convertirán en la fuente de la verdad y se podrán actualizar a ES6 Classes.

Noté que las variables del alcance del módulo no se eliminan durante la agitación. Puedes ver el comportamiento con estas cuatro variables, build/three.module.js:43059

const _position$3 = new Vector3();
const _quaternion$4 = new Quaternion();
const _scale$2 = new Vector3();
const _orientation$1 = new Vector3();

Parece que deberíamos marcar estos puros con el comentario especial-

const _position = /*@__PURE__*/ new Vector3();

¿Eso funciona para todos?

Me parece bien 👌

Genial, eso borra otras 144 líneas cuando el árbol tiembla con Color 🥳

¡Por favor, todos den a sus relaciones públicas abiertas el tratamiento /*@__PURE__*/ cuando tengan tiempo!

@ianpurvis genial! ¿Estás usando rollup, verdad? ¿podrías compartir tu configuración?

@mrdoob Finalmente pude hacer algunas pruebas. Personalmente uso webpack, así que hice algunas pruebas con él, mi configuración es esta si alguien está interesado .

Probé este código

import * as THREE from 'three'

console.log(THREE.WebGLRenderer)

0.119.1

0 119 1

0.120.1

0 120 1

Así que algo está siendo sacudido, ¡genial!

Mirándolo más, parece que la clase AudioListener no está en el paquete, ¡buenas noticias!

Screenshot 2020-09-01 at 16 49 22

Screenshot 2020-09-01 at 16 50 07

Webpack también elimina automáticamente las variables no utilizadas señaladas por @ianpurvis.


Después de esto, decidí probar métodos estáticos definidos fuera de la clase.

Screenshot 2020-09-01 at 16 50 37

y desafortunadamente, esto hace que la clase no se pueda sacudir en forma de árbol

Screenshot 2020-09-01 at 16 51 04


Después de investigar un poco más, noté que las clases de geometría como DodecahedronGeometry , que no se usaban en ninguna parte, todavía estaban en el paquete.

Screenshot 2020-09-01 at 16 51 29

Screenshot 2020-09-01 at 16 52 08

Más tarde descubrí que esto se debía a este objeto Geometries en el paquete three.module.js

Screenshot 2020-09-01 at 17 18 32

Que se genera automáticamente al usar patrones como este en el ObjectLoader . Esto probablemente desaparecerá cuando hagamos ObjectLoader una clase, y src/geometries se podrá sacudir.

@marcofugaro No hay problema, aquí está la configuración acumulativa

@marcofugaro Hola, agregué compatibilidad con webpack a shakediff... ¿te parece bien esta configuración de webpack ? Dado que terser es responsable de la eliminación del código inactivo en la sacudida del árbol del paquete web, es difícil evitar algunos artefactos de transformación en esas salidas. Pero si diferencia usando un algoritmo de histograma con espacios en blanco deshabilitados, es manejable. A partir de una prueba rápida esta noche, el paquete web parece aceptar tanto /*@__PURE__*/ como /*#__PURE__*/ . Creo que podemos estandarizar en uno u otro. Más mañana...

@ianpurvis No creo que tenga permitido instalar shakediff en mi máquina...

Screen Shot 2020-09-22 at 9 59 04 AM

De todos modos, hice una prueba simple:

import { WebGLRenderer } from './src/renderers/WebGLRenderer.js';
console.log( new WebGLRenderer() );

Y noté que Geometry no estaba siendo sacudido. https://github.com/mrdoob/three.js/pull/20394 lo arregla.

Luego intenté hacer:

import { Vector3 } from './src/math/Vector3.js';
console.log( new Vector3() );

Y noté que el resumen no sacude los métodos no utilizados... 😕

@mrdoob desafortunadamente, en el futuro previsible, ninguna herramienta podrá sacudir los métodos de clase. Diablos, ¡ni siquiera pueden ser minimizados!

Esto se debe a que en javascript, puede acceder a métodos como this['I am a string'] , al igual que puede acceder dinámicamente a las propiedades de los objetos. Por esta razón, las herramientas no saben de antemano si llamará a un método y cómo lo hará (podría ser this[variable] ).

Esto es lo mismo para las clases de ES6 y las clases de funciones. Por ejemplo, en three.min.js , los métodos se dejan intactos, como cualquier propiedad de objeto 🙂

¿Y nadie ha propuesto un modo "estricto" de constructor, donde se espera que no llame a métodos como this['I am a string'] ?

Ni idea 🤷‍♂️

Aquí hay una discusión sobre este tema con respecto al resumen: https://github.com/rollup/rollup/issues/349

los métodos de clase nunca serán sacudidos por ninguna herramienta. Diablos, ¡ni siquiera pueden ser minimizados!

Perdón por salirme del tema, pero puede hacer que la minificación funcione si le da al compilador alguna pista sobre qué es "público" versus "privado". En el pasado, he usado prefijos "_" en métodos para esto. Consulte https://github.com/developit/microbundle/wiki/mangle.json. Pero, desafortunadamente, tampoco tengo idea de si algo similar es posible para sacudir árboles. 😕

¡Guau! #20395 combinado! buen material @marcofugaro

¡Impresionantes noticias sobre babel y geometría!

@ianpurvis No creo que se me permita instalar shakediff en mi máquina...

@mrdoob Hm, parece que Parcel depende de esa versión de fsevents... tal vez pueda fijar eso en algo más alto.

Para tu información, aquí hay buena información sobre las mejoras en el movimiento de árboles en Webpack 5...

Para tu información, aquí hay buena información sobre las mejoras en el movimiento de árboles en Webpack 5...

Progreso... Espero que Rollup implemente esto también...

Hola a todos,

¿Cuáles son exactamente los objetivos de la propiedad .is**Classname** y this.type = **Classname** ?
¿No es un resto del antiguo patrón de pseudoclase?
¿Por qué no deshacerse de él por completo y reemplazar este uso por la forma normal de verificación de tipos?

obj instanceof Vector3  // prefer this one for inheritance
// or
obj.constructor === Vector3  // prefer this for no inheritance

Quiero decir, como parte de pasar a las clases ES, los objetos tendrán los tipos correctos ya verificables...

La biblioteca usaba obj instanceof Vector3 antes.
Pero Rich Harris implementó y cambió todos los controles a is* para permitir el movimiento de árboles: #9310

La biblioteca usaba obj instanceof Vector3 antes.
Pero Rich Harris implementó y cambió todos los controles a is* para permitir el movimiento de árboles: #9310

Gracias por la respuesta, había leído el hilo, por cierto, no entiendo por qué se debe evitar una clase para estar en la salida si alguna otra clase necesita verificar el tipo ... Quiero decir, si la clase X incluida necesita para tener en cuenta que un objeto es una clase B, entonces se usa la clase B (al menos para crear dicho objeto de alguna manera) y debe agruparse, ¿no es así?

Por ejemplo, WebGLRenderer necesita verificar si una geometría que representa es BufferGeometry o Geometry, pero nunca crea instancias de Geometry. La mayoría de las aplicaciones de three.js solo deberían usar BufferGeometry, por lo que queremos que la sacudida del árbol elimine Geometry (y sus subclases) del paquete cuando sea posible.

De forma visual...

Este patrón hace que WebGLRenderer siempre incluya Geometry al agrupar:

import { Geometry } from '../core/Geometry.js';
import { BufferGeometry } from '../core/BufferGeometry.js';

if ( geometry instanceof Geometry ) {
} else if ( geometry instanceof BufferGeometry ) {
}

Este patrón no:

if ( geometry.isGeometry === true ) {
} else if ( geometry.isBufferGeometry === true ) {
}

oigan todos,

Dado esto , ¿cuáles son nuestros pensamientos sobre seguir adelante desde aquí?

No creo que haya ningún cambio, todavía. Todo lo que (1) no esté en examples/js y (2) no esté extendido por algo en examples/js se puede convertir en Clases ES6. Si ese proceso está concluyendo, debemos decidir cuándo comenzar a cambiar examples/js a clases.

De memoria, y después de una mirada rápida, hemos hecho bastante y todavía hay algunas relaciones públicas listas esperando.

Podría intentar volver a compilar mi lista de dependencias/extendida en ejemplos.

@DefinitelyMaybe ¡Oye! Eso suena genial, tu lista fue muy útil. Y la estrategia de @donmccurdy tiene sentido para mí. 👍 Creo que sería mejor cerrar el trabajo que ya hemos hecho. #20070 sería un excelente PR para atacar porque puede brindar una estrategia para migrar variables privadas/ocultas a ES6 (necesitamos esto para la migración de renderers/webgl a ES6). Si todos pueden ejecutar los puntos de referencia o participar en la discusión allí, se lo agradecería. Creo que tenemos algunas opciones decentes, solo necesitamos asegurarnos de que el rendimiento sea bueno.

Okey,
Puedo comenzar algunas relaciones públicas para reescribir ejemplos en clases de ES ...
@mrdoob , ¿es un problema para usted hacer el script jsm to js o no? (Creo que no pero dime si prefieres que lo esperemos)

Antes de convertir el código de ejemplo en clases, primero se debe fusionar #20527, #20529 o una solución diferente. Salvo el código que cumpla las condiciones mencionadas en https://github.com/mrdoob/three.js/issues/19986#issuecomment -718308451.

@DefinitelyMaybe Dijiste en el primer comentario :

  • usar campos de clase

1) ¿Significa que podemos usar campos de clase para todo?
Al igual que :

class Light extends Object3D {

    type = 'Light';
    isLight = true;

    color = new Color;
    intensity = 1;

    constructor(color, intensity = 1) {

        super();

        this.color = new Color(color);
        this.intensity = intensity;

    }

    copy() {
        ...
    }
}

... o es solo para propiedad de .is* ?

Entonces, 2) ¿qué pasa con los constructores vacíos? La especificación ES2015 decía que los constructores con solo una llamada super() están implícitos si no se proporcionan, por lo que algunas clases secundarias se pueden definir realmente más fácilmente:

class MapControls extends OrbitControls {

    screenSpacePanning = false; // pan orthogonal to world-space direction camera.up

    mouseButtons = { LEFT: MOUSE.PAN, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.ROTATE };

    touches = { ONE: TOUCH.PAN, TWO: TOUCH.DOLLY_ROTATE };

}

Y 3) ¿qué pasa con los campos de clase privada?

class OrbitControls extends EventDispatcher {
    ...

    #offset = new Vector3();

    // so camera.up is the orbit axis
    #quat = new Quaternion().setFromUnitVectors( object.up, new Vector3( 0, 1, 0 ) ); <= this will go in constructor because of object.up
    #quatInverse = this.#quat.clone().inverse();

    #lastPosition = new Vector3();
    #lastQuaternion = new Quaternion();

    #twoPI = 2 * Math.PI;

    update() {
        ... ( no more closure and return function here )
    }

}

Chrome más reciente admite campos de clase públicos y privados de forma nativa ahora...

20395

La primera clave es pasar todas las pruebas.

Te encontrarás con menos problemas al principio si cambias menos.

@marcofugaro Creo que todavía hay algunas variables que se pueden cambiar en campos de clase, ¿verdad?
Estoy viendo cosas como:

class EdgesGeometry extends BufferGeometry {

    constructor( geometry, thresholdAngle ) {

        super();

        this.type = 'EdgesGeometry';

cambiado a:

class EdgesGeometry extends BufferGeometry {

    type = 'EdgesGeometry';

    constructor( geometry, thresholdAngle ) {

        super();

Es probable que nos encontremos con otras advertencias en el lugar, como cuando me encontré con " new this.contructor() != new Foo() ".

campos de clase privada

esta es una discusión en curso. Pasará un tiempo antes de que lo usemos si lo usamos. No estoy seguro de un problema o relaciones públicas que pueda indicarle.

@marcofugaro Creo que todavía hay algunas variables que se pueden cambiar a campos de clase, ¿verdad?
Estoy viendo cosas como:

Sí, eso se puede hacer ahora. Sin embargo, no podemos hacer eso para las propiedades .is* ya que no deben ser enumerables ni escribibles, para aquellas tenemos que usar Object.defineProperty(this, ... .

¿Cómo se comprueba de nuevo? ¿sería posible para nosotros usar la palabra clave static en lugar de Object.defineProperty(this, ... ?

¿Cómo se comprueba de nuevo? ¿sería posible para nosotros usar la palabra clave static en lugar de Object.defineProperty(this, ... ?

No lo creo, porque obj.is* tiene que estar en instancias, no en la clase en sí...

No estoy seguro de qué transpila babel exactamente en la configuración actual, pero podemos usar decoradores para establecer un campo de clase como no enumerable/no escribible:

import { unwrittable, unenumerable } from 'some/decorator/helpers.js'

class Foo {
    @unwrittable<strong i="12">@unenumerable</strong>
    isFoo = true;
}

@DefinitelyMaybe static las propiedades son diferentes, no son accesibles desde la instancia, sino desde la clase misma.

class Test {
  static staticProp = true

  constructor() {
    Object.defineProperty(this, 'definedProp', { value: true })
  }
}
const test = new Test()

console.log(test.staticProp, test.definedProp)

resultado:

undefined true


Editar: no importa lo que estaba diciendo ...
sí Sí.

Mi punto principal es que si tuviéramos que ajustar el código que verifica esta propiedad, podríamos pasar de:

class Test {
  constructor() {
    Object.defineProperty(this, 'definedProp', { value: true })
  }
}

a

class Test {
  static definedProp = true
  constructor() {
  }
}

Así que me preguntaba dónde y por qué se realiza este control y si podemos cambiarlo o no.

@DefinitelyMaybe El problema es obtener la información de un tipo de instancia. Entonces, si pudiera acceder a la clase de la instancia para obtener su accesorio estático, ¿por qué tener un accesorio estático? Ya tienes el nombre de la clase...

obj.constructor.isFoo == true
obj.constructor.name == 'Foo'

Editar: al escribir esto, pude darme cuenta de que tener varios .is * puede ser útil para probar en cada cadena de herencia finalmente, en comparación con solo el nombre de clase final único ...

obj.constructor.isFoo || obj.constructor.isBar || obj.constructor.isBaz

Edit2: sí, también se puede lograr lo mismo con los nombres de las clases finalmente, pero más complicado de probar ...

let types = getInheritanceNames(obj) // looping each .constructor.prototype.constructor.name
types.contains( 'Foo' ) || types.contains( 'Bar' ) || types.contains( 'Baz' ) 

de la instancia

UPS. vuelve a leer ese. sí, no importa lo que estaba diciendo.

if ( scope.object.isPerspectiveCamera ) {
...
}
if ( geometry.isBufferGeometry ) {
...
}
if ( material.isShaderMaterial ) {
...
}

derecho. Dos cosas.

  • ¿Qué nos queda?

debemos decidir cuándo comenzar a cambiar examples/js a las clases.

  • Cada vez más cerca de necesitar discutir esto para poder progresar.

No sé si deberíamos esperar al #20527 o al #20529 porque ambos intentarán recrear el examples/js en su forma actual, que no es lo que buscamos. Mi sugerencia inicial es comenzar a convertir examples/js tal cual. La pregunta es, ¿en qué problemas nos metemos...

También quería reiterar algo que @mrdoob dijo recientemente

Odiaría obligar a los novatos a aprender sobre polyfills o bundlers para renderizar su primer cubo.

Como alguien que ha estado trabajando con módulos durante el último tiempo, el flujo de trabajo es claro y entiendo los diversos conceptos necesarios para que algo funcione. No necesitamos empaquetadores ni rellenos polivalentes, pero tendremos que ajustar cómo se describe inicialmente Three.js.

Además, ¿quizás la adición de un REPL pero diseñado para Three.js podría ayudar en esta área? Un ejemplo es svelte's

También necesitaremos aclarar cómo reemplazar algunos patrones que no son de clase como:

function Foo() {

    this.update = function () {

        var priv = 'foo'

        return function update() {
            ...
        };

    }();

}

En mi humilde opinión, podríamos usar campos de clase privados y hacer que el resumen/babel se transponga al patrón anterior para ciertos navegadores antiguos que no implementan esto de forma nativa...

En mi humilde opinión, podríamos usar campos de clase privados y hacer que el resumen/babel se transponga al patrón anterior para ciertos navegadores antiguos que no implementan esto de forma nativa...

Estoy de acuerdo con esta estrategia, pero la decisión, por supuesto, depende de los mantenedores principales que necesitarán mantener ese código.

frio. Podría ser una idea mostrar esto dentro de src primero, es decir, encuentre un patrón similarmente extraño a lo que @devingfx describió dentro src , haga un PR que use variables privadas en su lugar y muestre lo que hace babel con eso.

¿Alguna sugerencia sobre qué guión?

búsquedas: internal , private , readonly 👀

espera, ¿todas las variables _* estaban destinadas a ser privadas?

...

Un elefante en esta habitación podría costar src/renderers/WebGLRenderer.js

¿Qué tal WebGLAnimation? Es una buena clase pequeña... https://github.com/mrdoob/three.js/pull/20070

¿Alguna sugerencia sobre qué guión?

Estoy enfocado en exemples/js y encontré esto en OrbitControls...

mostrar lo que babel hace con él.

Estoy bastante seguro de que no generará algo que coincida con el pensamiento de sintaxis de mrDoob 😅

a derecha.

y ups ¿Dónde está mi cerebro? Necesitaremos uno de #20527 o #20529 (u otro) para fusionar para comenzar a transformar la carpeta examples . examples/js se mantendrá en el futuro previsible, lo que significa que tocar la carpeta examples/js con clases es un absoluto no, no. eso rompería la compatibilidad con IE... suspiro.

hacer que el rollup/babel transpile al patrón anterior

Supongo que está pensando y apoyando a esos JSM a JS PR. Podemos apuntar a los examples/jsm una vez que se tome una decisión.

Agregar variables privadas a src sigue siendo una buena idea, ya que sería una buena solución al problema de larga data de "no juegues con esas variables, tienen un propósito específico".

tocar la carpeta examples/js con clases es un absoluto no, no.

Ooops, mi error, estaba hablando de indagar en exemples/jsm por supuesto, exemples/js será la versión "construida" en un futuro cercano...

eso rompería la compatibilidad con IE... suspiro.

¿¿¿Qué??? ¿Seguimos hablando de Internet Explorer en 2020? ¿Estamos hablando de la compatibilidad de una biblioteca WebGL en este dinosaurio de 7 años? Seriamente !! 1,4% ...
_(Deberíamos agregar un recopilador de estadísticas en la biblioteca para recopilar si TRES usuarios están planeando un uso en IE)_

😞 Por cierto, es por eso que babel existe...

Los archivos de compilación three.js y three.min.js , así como todos los archivos en examples/js aún deberían admitir navegadores más antiguos como IE 11.

Hubo un PR el año pasado que debería detener el soporte para IE 11 (# 18091), pero resultó que todavía hay usuarios que confían en este navegador. Y la política actual del proyecto es proporcionar los archivos correspondientes al usuario para que no realice la conversión de ES6 a ES5 por sí mismo. Esto también se discutió en #20455.

la política actual del proyecto es proporcionar los archivos correspondientes al usuario para que no realice la conversión de ES6 a ES5 por sí mismo.

De acuerdo, no hay problemas con esa política si la fuente se puede desarrollar de una manera moderna, y si se supone que las compilaciones resultantes no son legibles sino que simplemente funcionan ...
¡Porque los transpiladores generan un código tan feo!
Así que no veo problemas para que src se escriban en ESnext, y las compilaciones sean feas, PERO es un problema potencial con exemples/js si estos archivos deben ser legibles, comentados y bien formados...

Por cierto, me pregunto varias veces por qué algunos ejemplos son ejemplos y no fuentes principales.
Ejemplo: los controles generalmente se usan tal cual, se copian como complementos opcionales y no se usan como un ejemplo real que lee y del que se inspira para escribir sus proyectos, como un ejemplo de cubo giratorio, por ejemplo...

_(Empecé mi viaje con TRES con una búsqueda: "cubo rotativo webgl" y un ejemplo que condujo a un maratón de código de 1 noche desarrollando un pequeño juego con un cubo que se mueve en plataformas ^^)_

Cuando se usa una compilación adecuada, no importa qué archivos están en el núcleo y qué en el directorio de ejemplos. Siempre que el movimiento del árbol funcione correctamente, solo tendrá los archivos fuente en su compilación que realmente se requieren.

Para mí, la distinción entre núcleo y ejemplos proviene de una época en la que este tipo de flujo de trabajo aún no estaba disponible. El núcleo debe ser pequeño y compacto, ya que tuvo que importarlo completamente como un solo componente. Solo se deben incluir los archivos más _importantes_. Los archivos que terminaron en el núcleo fueron, en cierto sentido, una decisión caso por caso.

Cuando se usa una compilación adecuada, no importa qué archivos están en el núcleo y qué en el directorio de ejemplos. Siempre que el movimiento del árbol funcione correctamente, solo tendrá los archivos fuente en su compilación que realmente se requieren.

Esto es cierto solo para usuarios de módulos ES;)

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