Three.js: Passer aux cours ES6

Créé le 2 août 2020  ·  88Commentaires  ·  Source: mrdoob/three.js

Salut tout le monde,

J'ai estimé qu'il était approprié de créer un nouveau numéro (au lieu de continuer # 11552) pour aider davantage tout le monde à suivre et à mettre à jour les problèmes et les progrès liés au passage aux classes ES6. Cela devrait également être utile pour le document de publication.

Pour ceux qui souhaitent aider, consultez la liste ci-dessous et faites-nous savoir sur quoi vous aimeriez travailler. Un PR par classe est privilégié cependant certains dossiers peuvent être réalisés en une seule fois . Si un fichier particulier ne peut pas être converti, faites une note en haut du fichier ou envoyez-moi un ping depuis votre PR et je le noterai ci-dessous.

Remarques:

  • pour Class.prototype.is** utiliser Object.defineProperty( this, 'is**', { value: true } );
  • les champs de classe sont également disponibles le cas échéant #20395
  • new this.contructor() != new Foo() ... discussion connexe .
  • Cochera après avoir fusionné et terminé.

Partie 1 : src

  • [ ] source

    • [ ] Animation ( #19964, #20014, #20016 )

    • [ ] pistes ( #20013 )

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

    • [ ] caméras ( #20102 )

    • [ ] noyau ( #19976, #19977, #19978, #19984, #20008 )

    • [x] suppléments ( #19979 )

    • [ ] noyau ( #20656 )



      • Courbe laissée de côté telle qu'elle est étendue dans les exemples



    • [ ] courbes ( #20140 )

    • [ ] objets ( )



      • Utilisé dans examples/objects/MarchingCubes.js , devra attendre. réf #20030



    • [x] géométries ( #19994 )

    • [x] aides ( #19996 )

    • [ ] lumières ( #20018 )

    • [ ] chargeurs ( #19985 )

    • Le chargeur de base ne peut pas encore être fait

    • [ ] matériaux ( #20100 )

    • [x] mathématiques ( #19980, #19997, #20076, #20089)

    • Interpolants attendra que nous nous attaquions à examples/js

    • [ ] objets (#20658 )

    • [ ] rendus ( #20101 )

    • [ ] webgl ( #20070 )

    • [ ] webxr ( #20038 )

    • [x] scènes ( #20007 )

    • [ ] textures ( #20009 )

Nous ne sommes pas encore prêts pour la partie 2. Une discussion s'impose.

Partie 2 : exemples

  • [ ] exemples

    • [ ] animations

    • [ ] appareils photo

    • [ ] contrôles

    • [ ] courbes

    • [ ] effets

    • [ ] exportateurs

    • [ ] géométries

    • [ ] interactif

    • [ ] lumières

    • [ ] lignes

    • [ ] chargeurs

    • [ ] math

    • [ ] divers

    • [ ] modificateurs

    • [ ] objets

    • [ ] post-traitement

    • [ ] moteurs de rendu

    • [ ] shaders

Partie 3 : Fins libres et rangement

  • [ ] src/core/Object3D
    ...

Commentaire le plus utile

@ianpurvis génial ! utilisez-vous le cumul, n'est-ce pas ? pourrais-tu partager ta config ?

@mrdoob J'ai finalement pu faire des tests. Personnellement, j'utilise webpack, j'ai donc fait quelques tests avec, ma config est celle-ci si quelqu'un est intéressé .

j'ai testé ce code

import * as THREE from 'three'

console.log(THREE.WebGLRenderer)

0.119.1

0 119 1

0.120.1

0 120 1

Donc, quelque chose est en train d'être secoué, super !

En y regardant de plus près, il semble que la classe AudioListener ne soit pas dans le bundle, bonne nouvelle !

Screenshot 2020-09-01 at 16 49 22

Screenshot 2020-09-01 at 16 50 07

Webpack supprime également automatiquement les variables inutilisées signalées par @ianpurvis.


Après cela, j'ai décidé de tester des méthodes statiques définies en dehors de la classe

Screenshot 2020-09-01 at 16 50 37

et malheureusement, cela rend la classe non tree-shakeable

Screenshot 2020-09-01 at 16 51 04


Après avoir creusé un peu plus, j'ai remarqué que des classes de géométrie comme DodecahedronGeometry , qui n'étaient utilisées nulle part, étaient toujours dans le bundle

Screenshot 2020-09-01 at 16 51 29

Screenshot 2020-09-01 at 16 52 08

Plus tard, j'ai découvert que cela était dû à cet objet Geometries dans le paquet three.module.js

Screenshot 2020-09-01 at 17 18 32

Qui est généré automatiquement lors de l'utilisation de modèles comme celui-ci dans ObjectLoader . Cela disparaîtra probablement lorsque nous créerons ObjectLoader une classe, et src/geometries sera ébranlable.

Tous les 88 commentaires

J'appellerai dibs sur le reste du dossier audio 🔈

hey @mrdoob , pourriez-vous s'il vous plaît préciser comment vous aimeriez que nous traitions les scripts dans le dossier des exemples ?

J'aime #19989 aller directement à la conversion mais je me rends compte que ce faisant, le utils/modularize.js ne peut plus être utilisé sur le dossier examples/js sans écraser ce travail. Cela marque-t-il la fin du maintien des examples/js et le début de seulement examples/jsm ?

edit : voir commentaire

Pourrais-je travailler sur le reste du dossier maths ?

Pourrais-je travailler sur le reste du dossier maths ?

Je suis tout à fait d'accord pour que tu essaies. Je me souviens d'avoir essayé il y a quelque temps, mais @ Mugen87 a fini par me le reprocher. Un résumé rapide de cela a été testé au fur et à mesure, car la conversion de l'ensemble du dossier en une seule fois pourrait vous mettre en difficulté. Un partiel, voire dossier par dossier, serait le bienvenu j'en suis sûr.

@DefinitelyMaybe Je verrai quoi d'autre peut être migré sous src/animation/

agréable. Je pense que ce dossier est presque terminé. Peut-être qu'il ne reste que src/core/Object3D.js et src/core/BufferGeometry.js ?

Peut-être qu'il ne reste que src/core/Object3D.js et src/core/BufferGeometry.js ?

Oui, il y a beaucoup de classes ES5 qui dépendent de Object3D et BufferGeometry .

Tirez, il y a eu des progrès incroyables à ce sujet 🎉

Je vais appeler dibs sur src/lights . Ouvrez les src/extras et src/renderers dans la liste ci-dessus, il s'avère qu'il y a quelques dossiers dans chacun à parcourir.

Salut à tous,

que faisions-nous par rapport à ce modèle ?

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

est-ce maintenant :

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

ou

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

actuellement, j'ai fait le second mais en le regardant, je dirais que l'intention de cela aurait pu être plus proche du premier.

est-ce que quelqu'un sait ce qui utilisait ces variables en premier lieu ?

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

☝️ C'est vrai. isDirectionalLight est un bon exemple, il s'utilise comme ceci :

$ 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 ) {

Cela dit, il pourrait y avoir des gains de performances en conservant certaines propriétés du prototype...

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

Peut-être pouvons-nous examiner ceux du PR au cas par cas.

Je vais tenter ma chance à src/renderers/webgl 👍 👍

bonne chance, amuse toi bien. celui-là s'y passe pas mal

Salut à tous, j'ai converti src/renderers/webgl . C'était fou. Je vais continuer à tout revoir et attendre # 20039 avant de commencer à pousser les PR.

👍
j'ai hâte d'y être

J'ai remarqué que @yomotsu utilisait des getters en lecture seule pour les propriétés is* dans le PR mathématique... C'est peut-être le meilleur !

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

hum c'est possible. Je sais que d'autres ont essayé par endroits de rendre les variables immuables. Cela ressemble à un modèle assez décent pour moi.

vitrine rapide jsfiddle

Il semble que ce soit la voie à suivre :

foo.prototype.isDirectionalLight = true;

va se pencher sur src/objects . verra jusqu'où je peux aller sans casser des choses.

Le dossier de mathématiques vient d'être terminé.
( Les classes interpolées sont exclues. )

salut à tous,
Je vais arrêter de travailler sur src/objects , quelqu'un d'autre est plus que bienvenu pour le récupérer en attendant.

Hé, bon travail avec ces gars ! 💪

Un seul problème, foo.prototype.isDirectionalLight = true; ne permet pas encore de secouer l'arborescence, puisque la classe est modifiée sur place.
De plus, à ce stade, je suggérerais fortement de ne plus toucher au prototype puisque nous utilisons maintenant des classes et que le prototype peut être abstrait.

Qu'en est-il de ce modèle? C'est ce qui me semble le plus explicite.

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

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

Il y a aussi la version courte, qui fait la même chose mais est un peu plus implicite.

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

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

@marcofugaro la version courte me va bien 👍

Ok, fait PR.

De plus, je viens de remarquer que nous ne pouvons pas utiliser les champs de classe car nous sommes bloqués par ce PR .

Je peux mettre à jour le pipeline de construction pour utiliser le plus populaire @rollup/plugin-babel

Je peux mettre à jour le pipeline de construction pour utiliser le plus populaire @rollup/plugin-babel
et résolvez ce problème si vous le souhaitez.

Ouais, ce serait génial si vous pouviez faire un PR 🙏

@marcofugaro , @mrdoob youpi ! Oui s'il vous plaît

Salut tout le monde, avertissement rapide que j'ai mis à jour #20014 avec Object.defineProperty et également corrigé la sous-classe de AnimationClip . Si quelqu'un a le temps de l'examiner, j'apprécierais le supplément 👀 🙇 🙇

D'accord. Maintenant que r120 est sorti... quelqu'un pourrait-il vérifier que les choses sont correctement secouées ?

On dirait que ça marche un peu pour moi, mais légèrement.
Je ne vois plus ArrowHelper dans mon fichier bundle avec webpack. mais de nombreux codes inutiles existent toujours😢

qu'en est-il de la taille du paquet ? avant et après

Salut tout le monde, j'ai eu une idée et j'ai créé un outil appelé shakediff . Vous pouvez l'exécuter comme ceci :

$ shakediff builds/three.module.js Color

Cela générera un petit module important Color , le regroupera avec trois, puis créera un diff de trois à partir des métadonnées du cumul. Vous pouvez soit travailler avec le diff détaillé, soit simplement le diriger vers diffstat pour obtenir le niveau supérieur :

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

Pour le moment, il n'y a pas de package, mais vous pouvez l'installer à partir de mon référentiel si vous souhaitez l'essayer. Commentaires appréciés ! ✌️

npm -g i ianpurvis/shakediff.git

hey @mrdoob , pourriez-vous s'il vous plaît préciser comment vous aimeriez que nous traitions les scripts dans le dossier des exemples ?
J'aime # 19989 aller directement à la conversion mais je me rends compte que ce faisant, utils/modularize.js ne peut plus être utilisé sur le dossier examples/js sans écraser ce travail. Cela marque-t-il la fin de la maintenance des exemples/js et le début des exemples/jsm ?

Quel est le verdict sur celui-ci @mrdoob ? Serait-il judicieux de faire de jsm la source de vérité afin que nous puissions convertir des exemples en classes ES6 ? Peut-être pouvons-nous créer utils/demodularize.js pour prendre en charge la conversion dans l'autre sens ?

Le dossier examples/js sera supprimé en décembre 2020. Jusque-là, nous devons laisser le dossier tel quel, sans mettre à niveau son contenu - ou les fichiers examples/jsm générés à partir de son contenu - vers ES6 Classes. Après cette date, les fichiers examples/jsm deviendront la source de vérité et pourront être mis à jour vers les classes ES6.

J'ai remarqué que les variables de portée de module ne sont pas supprimées lors de l'agitation. Vous pouvez voir le comportement avec ces quatre 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();

On dirait que nous devrions marquer ces purs avec le commentaire spécial-

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

Est-ce que ça marche pour tout le monde ?

Ça me tente bien 👌

Bien, cela supprime encore 144 lignes lorsque l'arbre secoue avec Color 🥳

S'il vous plaît, tout le monde donne à vos relations publiques ouvertes le traitement /*@__PURE__*/ quand vous en avez le temps !

@ianpurvis génial ! utilisez-vous le cumul, n'est-ce pas ? pourrais-tu partager ta config ?

@mrdoob J'ai finalement pu faire des tests. Personnellement, j'utilise webpack, j'ai donc fait quelques tests avec, ma config est celle-ci si quelqu'un est intéressé .

j'ai testé ce code

import * as THREE from 'three'

console.log(THREE.WebGLRenderer)

0.119.1

0 119 1

0.120.1

0 120 1

Donc, quelque chose est en train d'être secoué, super !

En y regardant de plus près, il semble que la classe AudioListener ne soit pas dans le bundle, bonne nouvelle !

Screenshot 2020-09-01 at 16 49 22

Screenshot 2020-09-01 at 16 50 07

Webpack supprime également automatiquement les variables inutilisées signalées par @ianpurvis.


Après cela, j'ai décidé de tester des méthodes statiques définies en dehors de la classe

Screenshot 2020-09-01 at 16 50 37

et malheureusement, cela rend la classe non tree-shakeable

Screenshot 2020-09-01 at 16 51 04


Après avoir creusé un peu plus, j'ai remarqué que des classes de géométrie comme DodecahedronGeometry , qui n'étaient utilisées nulle part, étaient toujours dans le bundle

Screenshot 2020-09-01 at 16 51 29

Screenshot 2020-09-01 at 16 52 08

Plus tard, j'ai découvert que cela était dû à cet objet Geometries dans le paquet three.module.js

Screenshot 2020-09-01 at 17 18 32

Qui est généré automatiquement lors de l'utilisation de modèles comme celui-ci dans ObjectLoader . Cela disparaîtra probablement lorsque nous créerons ObjectLoader une classe, et src/geometries sera ébranlable.

@marcofugaro Pas de problème, voici la configuration du rollup

@marcofugaro Bonjour, j'ai ajouté la prise en charge de webpack à shakediff... cette configuration de webpack vous semble-t-elle correcte ? Étant donné que terser est responsable de l'élimination du code mort dans l'arborescence de webpack, il est difficile d'empêcher certains artefacts de transformation dans ces sorties. Mais si vous utilisez un algorithme d'histogramme avec les espaces blancs désactivés, cela est gérable. D'après un test rapide ce soir, webpack semble accepter à la fois /*@__PURE__*/ et /*#__PURE__*/ . Je pense que nous pouvons standardiser l'un ou l'autre. La suite demain...

@ianpurvis Je ne pense pas avoir le droit d'installer shakediff sur ma machine...

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

Quoi qu'il en soit, j'ai fait un test simple:

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

Et j'ai remarqué que Geometry n'était pas secoué. https://github.com/mrdoob/three.js/pull/20394 le corrige.

J'ai ensuite essayé de faire :

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

Et remarqué que le cumul ne secoue pas les méthodes inutilisées... 😕

@mrdoob malheureusement, dans un avenir prévisible, les méthodes de classe ne seront jamais ébranlables par n'importe quel outil. Heck, ils ne peuvent même pas être minifiés!

En effet, en javascript, vous pouvez accéder à des méthodes telles que this['I am a string'] , tout comme vous pouvez accéder dynamiquement aux propriétés de l'objet. Pour cette raison, les outils ne savent pas à l'avance si et comment vous allez appeler une méthode (peut-être this[variable] ).

C'est la même chose pour les classes ES6 et les classes Function. Par exemple, dans three.min.js , les méthodes ne sont pas modifiées, comme n'importe quelle propriété d'objet 🙂

Et personne n'a proposé un mode de construction "strict", où vous n'êtes pas censé appeler des méthodes comme this['I am a string'] ?

Aucune idée 🤷‍♂️

Voici une discussion sur ce sujet concernant le cumul : https://github.com/rollup/rollup/issues/349

les méthodes de classe ne seront jamais modifiables par n'importe quel outil. Heck, ils ne peuvent même pas être minifiés!

Désolé d'être hors sujet, mais vous pouvez faire fonctionner la minification si vous donnez au compilateur un indice sur ce qui est "public" par rapport à "privé". Dans le passé, j'ai utilisé des préfixes "_" sur les méthodes pour cela. Voir https://github.com/developit/microbundle/wiki/mangle.json. Mais, malheureusement, je n'ai aucune idée non plus si quelque chose de similaire est possible pour le secouage des arbres. 😕

Oh ! #20395 fusionné ! bonne chose @marcofugaro

Des nouvelles géniales sur babel et la géométrie !

@ianpurvis Je ne pense pas avoir le droit d'installer shakediff sur ma machine...

@mrdoob Hm, on dirait que Parcel dépend de cette version de fsevents... peut-être que je peux l'épingler à quelque chose de plus élevé.

Pour votre information, de bonnes informations ici sur les améliorations apportées au secouage des arbres dans Webpack 5 ...

Pour votre information, de bonnes informations ici sur les améliorations apportées au secouage des arbres dans Webpack 5 ...

Progrès... J'espère que Rollup implémentera cela aussi...

Salut tout le monde,

Quels sont les objectifs de la propriété .is**Classname** et this.type = **Classname** exactement ?
N'est-ce pas un reste de l'ancien modèle de pseudo-classe?
Pourquoi ne pas s'en débarrasser totalement et remplacer cet usage par la vérification de type normale ?

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

Je veux dire, dans le cadre du passage aux classes ES, les objets auront des types corrects déjà vérifiables ...

La bibliothèque utilisait obj instanceof Vector3 auparavant.
Mais Rich Harris a implémenté et changé toutes les vérifications en is* pour permettre le tree-shaking : #9310

La bibliothèque utilisait obj instanceof Vector3 auparavant.
Mais Rich Harris a implémenté et changé toutes les vérifications en is* pour permettre le tree-shaking : #9310

Merci pour la réponse, j'avais lu le fil, mais je ne comprends pas pourquoi une classe doit être évitée pour être dans la sortie si une autre classe doit la vérifier par type ... Je veux dire si la classe X groupée a besoin pour être conscient qu'un objet est une classe B, alors la classe B est utilisée (au moins pour créer ledit objet d'une manière ou d'une autre) et doit être regroupée, n'est-ce pas?

Par exemple, WebGLRenderer doit vérifier si une géométrie qu'il rend est BufferGeometry ou Geometry, mais il ne crée jamais d'instances Geometry. La plupart des applications three.js ne doivent utiliser que BufferGeometry, et nous voulons donc que l'arborescence élimine Geometry (et ses sous-classes) du bundle lorsque cela est possible.

D'une manière visuelle...

Ce modèle fait WebGLRenderer inclut toujours Geometry lors du regroupement :

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

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

Ce modèle ne :

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

salut à tous,

compte tenu de cela , quelles sont nos pensées pour aller de l'avant à partir d'ici ?

Je ne pense pas qu'il y ait encore de changement. Tout ce qui (1) n'est pas dans examples/js et (2) n'est pas étendu par quelque chose dans examples/js peut être converti en classes ES6. Si ce processus se termine, nous devrions décider quand commencer à passer examples/js aux classes.

De mémoire, et après un rapide coup d'œil, nous avons fait un bon bout de chemin et il y a encore des relations publiques prêtes à attendre.

Je pourrais essayer de recompiler ma liste de dépendances/extended-in-examples.

@ Certainement peut-être Hé ! Cela sonne bien, votre liste a été super utile. Et la stratégie de @donmccurdy a du sens pour moi. 👍 Je pense qu'il serait préférable de boucler le travail que nous avons déjà fait. #20070 serait un excellent PR à attaquer car il peut donner une stratégie pour migrer des variables privées/cachées vers ES6 (nous en avons besoin pour la migration de renderers/webgl vers ES6). Si tout le monde peut exécuter les points de repère ou participer à la discussion là-bas, je l'apprécierais. Je pense que nous avons quelques options décentes, il suffit de s'assurer que les performances sont bonnes.

D'accord,
Je peux commencer quelques relations publiques pour réécrire des exemples dans les classes ES...
@mrdoob est-ce un problème pour vous de faire le script jsm to js ou non? (Je pense que non mais dis-moi si tu préfères qu'on attende)

Avant de convertir l'exemple de code en classes, #20527, #20529 ou une solution différente doit d'abord être fusionnée. Sauf pour le code qui remplit les conditions mentionnées dans https://github.com/mrdoob/three.js/issues/19986#issuecomment -718308451.

@DefinitelyMaybe Vous avez dit dans le 1er commentaire :

  • utiliser les champs de classe

1) Cela signifie-t-il que nous pouvons utiliser des champs de classe pour tout ?
Ainsi :

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() {
        ...
    }
}

... ou c'est pour la propriété .is* seulement ?

Alors, 2) qu'en est-il des constructeurs vides ? La spécification ES2015 a déclaré que les constructeurs avec seulement un appel super() sont implicites s'ils ne sont pas fournis, donc certaines classes enfants peuvent être vraiment définies plus facilement :

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 };

}

Et 3) qu'en est-il des champs de classe privée ?

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 )
    }

}

Le dernier Chrome prend désormais en charge les champs de classe publics et privés de manière native...

20395

La première clé est de réussir tous les tests.

Vous rencontrerez moins de problèmes au départ en changeant moins.

@marcofugaro Je crois qu'il y a encore des variables qui peuvent être changées en champs de classe, n'est-ce pas?
Je regarde des choses comme:

class EdgesGeometry extends BufferGeometry {

    constructor( geometry, thresholdAngle ) {

        super();

        this.type = 'EdgesGeometry';

changé en:

class EdgesGeometry extends BufferGeometry {

    type = 'EdgesGeometry';

    constructor( geometry, thresholdAngle ) {

        super();

Il est probable que nous rencontrions d'autres mises en garde autour de l'endroit, comme la façon dont j'ai rencontré " new this.contructor() != new Foo() ".

champs de classe privée

c'est une discussion en cours. Il faudra un certain temps avant de l'utiliser si nous l'utilisons. Je ne suis pas sûr d'un problème ou d'un PR vers lequel je peux vous diriger.

@marcofugaro Je crois qu'il y a encore des variables qui peuvent être changées en champs de classe, n'est-ce pas?
Je regarde des choses comme:

Ouais ça peut se faire maintenant. Cependant, nous ne pouvons pas le faire pour les propriétés .is* car elles doivent être non énumérables et non inscriptibles, pour celles-ci, nous devons utiliser Object.defineProperty(this, ... .

comment est-il vérifié à nouveau? Serait-il possible pour nous d'utiliser le mot clé static au lieu de Object.defineProperty(this, ... ?

comment est-il vérifié à nouveau? Serait-il possible pour nous d'utiliser le mot clé static au lieu de Object.defineProperty(this, ... ?

Je ne pense pas, parce que obj.is* doivent être sur des instances, pas sur la classe elle-même...

Je ne sais pas exactement ce que babel transpile dans la configuration actuelle, mais nous pouvons utiliser des décorateurs pour définir un champ de classe comme non énumérable/non inscriptible :

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

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

@DefinitelyMaybe Les propriétés static sont différentes, elles ne sont pas accessibles depuis l'instance, mais plutôt depuis la classe elle-même.

class Test {
  static staticProp = true

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

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

résultat:

undefined true


Edit : peu importe ce que je disais...
Oui oui.

Mon point principal étant que si nous devions ajuster le code qui vérifie cette propriété, nous pourrions passer de :

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

à

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

Je me demandais donc où et pourquoi ce contrôle avait lieu et si oui ou non nous pouvions le changer.

@DefinitelyMaybe Le problème est d'obtenir les informations d'un type d'instance. Donc, si vous pouviez accéder à la classe de l'instance pour obtenir son accessoire statique, alors pourquoi avoir un accessoire statique ? Vous avez déjà le nom de la classe...

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

Edit: en écrivant ceci, j'ai pu comprendre qu'avoir plusieurs .is * peut être utile pour tester finalement sur chaque chaîne d'héritage, par rapport au seul nom de classe final unique ...

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

Edit2 : oui aussi on peut faire la même chose avec les noms de classes enfin, mais plus compliqué à tester...

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

de l'instance

Oups. relisez celui-là. ouais, peu importe ce que je disais.

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

à droite. Deux choses.

  • Que nous reste-t-il ?

nous devrions décider quand commencer à passer examples/js aux classes.

  • Se rapprocher de la nécessité d'en discuter pour progresser.

Je ne sais pas si nous devrions attendre #20527 ou #20529 parce qu'ils essaieront tous les deux de recréer le examples/js dans sa forme actuelle, ce qui n'est pas notre objectif. Ma suggestion initiale est de commencer à convertir examples/js tel quel. La question est, quels problèmes allons-nous avoir...

Je voulais aussi réitérer quelque chose que @mrdoob a dit récemment

Je détesterais forcer les débutants à se renseigner sur les polyfills ou les bundlers afin de rendre leur premier cube.

En tant que personne qui travaille avec des modules depuis un petit moment, le flux de travail est clair et je comprends les différents concepts nécessaires pour que quelque chose fonctionne. Nous n'avons pas besoin de bundlers et de polyfills mais nous devrons ajuster la façon dont Three.js est initialement décrit .

De plus, peut-être que l'ajout d'un REPL mais adapté à Three.js pourrait aider dans ce domaine ? Un exemple étant celui de Svelte

Nous devrons également clarifier comment remplacer certains modèles non-classes tels que :

function Foo() {

    this.update = function () {

        var priv = 'foo'

        return function update() {
            ...
        };

    }();

}

À mon humble avis, nous pourrions utiliser des champs de classe privés et faire en sorte que le cumul/babel transpile vers l'ancien modèle pour certains anciens navigateurs qui ne l'implémentent pas de manière native...

À mon humble avis, nous pourrions utiliser des champs de classe privés et faire en sorte que le cumul/babel transpile vers l'ancien modèle pour certains anciens navigateurs qui ne l'implémentent pas de manière native...

Je suis d'accord avec cette stratégie, mais la décision dépend bien sûr des responsables principaux qui devront maintenir ce code.

cool. Ce pourrait être une idée de montrer cela dans src d'abord, c'est-à-dire de trouver un modèle similaire à ce que @devingfx a décrit dans src , de créer un PR qui utilise des variables privées à la place et de montrer ce que babel fait avec ça.

des suggestions sur quel script?

recherches : internal , private , readonly 👀

attendez, toutes les variables _* étaient-elles censées être privées ?

...

Un éléphant dans cette pièce pourrait être src/renderers/WebGLRenderer.js

Que diriez-vous de WebGLAnimation, c'est une jolie petite classe... https://github.com/mrdoob/three.js/pull/20070

des suggestions sur quel script?

Je me concentre sur exemples/js et j'ai trouvé ça sur OrbitControls...

montrer ce que Babel en fait.

Je suis presque sûr que cela ne produira pas quelque chose correspondant à la pensée de syntaxe de mrDoob 😅

à droite.

et oups. Où est mon cerveau... nous aurons besoin de l'un des #20527 ou #20529 (ou autre) pour fusionner afin de commencer à transformer le dossier examples . examples/js reste dans les parages dans un avenir prévisible, ce qui signifie que toucher le dossier examples/js avec les classes est un non absolu. cela briserait la compatibilité avec IE... soupir.

faire le rollup/babel transpiler à l'ancien modèle

Devinez sa réflexion et son soutien à ces JSM à JS PR. Nous pouvons viser les examples/jsm une fois qu'une décision est prise.

L'ajout de variables privées dans src est toujours une bonne idée car ce serait une bonne solution au problème de longue date de "s'il vous plaît, ne jouez pas avec ces variables, elles ont un but précis"

toucher le dossier examples/js avec les classes est un non absolu.

Oups, mon mauvais, je parlais de creuser dans exemples/jsm bien sûr, exemples/js sera la version "construite" dans un avenir proche...

cela briserait la compatibilité avec IE... soupir.

Quoi??? Parlons-nous encore d'Internet Explorer en 2020 ? Parlons-nous de la compatibilité d'une librairie WebGL sur ce dinosaure de 7 ans ? Sérieusement !! 1,4% ...
_(nous devrions ajouter un collecteur de statistiques dans la bibliothèque pour recueillir si un utilisateur TROIS envisage une utilisation sous IE)_

😞 D'ailleur, c'est pour ça que babel existe...

Les fichiers de construction three.js et three.min.js ainsi que tous les fichiers dans examples/js devraient toujours prendre en charge les anciens navigateurs comme IE 11.

Il y a eu un PR l'année dernière qui devrait arrêter le support pour IE 11 (#18091) mais il s'est avéré qu'il y a encore des utilisateurs qui comptent sur ce navigateur. Et la politique actuelle du projet est de fournir les fichiers respectifs à l'utilisateur afin qu'il n'effectue pas lui-même la conversion ES6 vers ES5. Cela a également été discuté dans # 20455.

la politique actuelle du projet est de fournir les fichiers respectifs à l'utilisateur afin qu'il n'effectue pas lui-même la conversion ES6 vers ES5.

D'accord, pas de problème avec cette politique si la source peut être développée de manière moderne, et si les versions résultantes ne sont pas censées être lisibles mais simplement fonctionnelles...
Parce que les transpilers produisent un code si laid !
Donc je ne vois aucun problème pour que src soit écrit dans ESnext, et que les builds soient laids, MAIS c'est un problème potentiel avec exemples/js si ces fichiers doivent être lisibles, commentés et bien formés...

BTW je me demande plusieurs fois pourquoi certains exemples sont des exemples et non des sources principales !?
Exemple : les contrôles sont généralement utilisés tels quels, copiés comme des addons optionnels et non utilisés comme un véritable exemple que vous lisez et dont vous vous inspirez pour écrire vos projets, comme un exemple de cube rotatif par exemple...

_(J'ai commencé mon voyage avec TROIS par une recherche : "cube rotatif webgl" et un exemple de celui-ci menant à un marathon de code d'une nuit en développant un petit jeu avec un cube se déplaçant sur des plateformes ^^)_

Lorsque vous utilisez une construction appropriée, peu importe quels fichiers se trouvent dans le noyau et ceux dans le répertoire des exemples. Tant que le secouage d'arborescence fonctionne correctement, vous n'avez que les fichiers source dans votre build qui sont réellement nécessaires.

Pour moi, la distinction entre noyau et exemples vient d'une époque où ce type de flux de travail n'était pas encore disponible. Le noyau doit être petit et compact car vous deviez l'importer complètement en tant que composant unique. Seuls les fichiers les plus _importants_ doivent être inclus. Les fichiers qui se sont retrouvés dans le noyau étaient en quelque sorte une décision au cas par cas.

Lorsque vous utilisez une construction appropriée, peu importe quels fichiers se trouvent dans le noyau et ceux dans le répertoire des exemples. Tant que le secouage d'arborescence fonctionne correctement, vous n'avez que les fichiers source dans votre build qui sont réellement nécessaires.

Ceci est vrai pour les utilisateurs des modules ES uniquement ;)

Cette page vous a été utile?
0 / 5 - 0 notes