Three.js: Movendo-se para as classes ES6

Criado em 2 ago. 2020  ·  88Comentários  ·  Fonte: mrdoob/three.js

Olá a todos,

Achei apropriado criar um novo problema (em vez de continuar #11552) para ajudar ainda mais a todos a acompanhar e atualizar os problemas e o progresso em torno da mudança para as classes ES6. Isso também deve ser útil para o documento de lançamento.

Para aqueles que desejam ajudar, veja a lista abaixo e deixe-nos saber em que você gostaria de trabalhar. Um PR por aula é favorecido, no entanto, algumas pastas podem ser feitas de uma só vez . Se um arquivo específico não puder ser convertido, faça uma anotação na parte superior do arquivo ou envie-me um ping do seu PR e anotarei abaixo.

Notas:

  • por Class.prototype.is** use Object.defineProperty( this, 'is**', { value: true } );
  • campos de classe também estão disponíveis se apropriado #20395
  • new this.contructor() != new Foo() ... discussão relacionada .
  • Marcará após mesclado e concluído.

Parte 1: src

  • [ ] src

    • [] animação (#19964, #20014, #20016)

    • [ ] faixas ( #20013 )

    • [x] áudio (#19975, #20003)

    • [ ] câmeras ( #20102 )

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

    • [x] extras ( #19979 )

    • [ ] núcleo ( #20656 )



      • Curva omitida como estendida nos exemplos



    • [ ] curvas (#20140)

    • [ ] objetos ( )



      • Usado em examples/objects/MarchingCubes.js , terá que esperar. referência nº 20030



    • [x] geometrias ( #19994 )

    • [x] ajudantes (#19996)

    • [ ] luzes (#20018)

    • [ ] carregadores ( #19985 )

    • O carregador de base ainda não pode ser feito

    • [ ] materiais ( #20100 )

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

    • Os interpoladores vão esperar até atacarmos examples/js

    • [ ] objetos (#20658 )

    • [ ] renderizadores ( #20101 )

    • [ ] webgl (#20070)

    • [ ] webxr (#20038)

    • [x] cenas (#20007)

    • [ ] texturas (#20009)

Ainda não estamos prontos para a Parte 2. A discussão é necessária.

Parte 2: exemplos

  • [ ] exemplos

    • [ ] animação

    • [ ] câmeras

    • [ ] controles

    • [ ] curvas

    • [ ] efeitos

    • [ ] exportadores

    • [ ] geometrias

    • [ ] interativo

    • [ ] luzes

    • [ ] linhas

    • [ ] carregadores

    • [ ] matemática

    • [ ] diversos

    • [ ] modificadores

    • [ ] objetos

    • [ ] pós-processamento

    • [ ] renderizadores

    • [ ] sombreadores

Parte 3: Solte as pontas e arrume

  • [ ] src/core/Object3D
    ...

Comentários muito úteis

@ianpurvis ótimo! você está usando o rollup, certo? poderia compartilhar sua configuração?

@mrdoob Finalmente consegui fazer alguns testes. Eu pessoalmente uso webpack, então fiz alguns testes com ele, minha configuração é essa se alguém se interessar .

testei esse código

import * as THREE from 'three'

console.log(THREE.WebGLRenderer)

0.119.1

0 119 1

0,120,1

0 120 1

Então, algo está sendo sacudido pela árvore, ótimo!

Olhando mais para isso, parece que a classe AudioListener não está no pacote, ótimas notícias!

Screenshot 2020-09-01 at 16 49 22

Screenshot 2020-09-01 at 16 50 07

O Webpack também remove automaticamente as variáveis ​​não utilizadas apontadas por @ianpurvis.


Depois disso, decidi testar métodos estáticos definidos fora da classe

Screenshot 2020-09-01 at 16 50 37

e, infelizmente, isso torna a classe não agitável

Screenshot 2020-09-01 at 16 51 04


Depois de fazer mais algumas escavações, notei que classes de geometria como DodecahedronGeometry , que não eram usadas em nenhum lugar, ainda estavam no pacote

Screenshot 2020-09-01 at 16 51 29

Screenshot 2020-09-01 at 16 52 08

Mais tarde eu descobri, isso era devido a este objeto Geometries three.module.js no pacote three.module.js

Screenshot 2020-09-01 at 17 18 32

Que é gerado automaticamente ao usar padrões como este no ObjectLoader . Isso provavelmente desaparecerá quando fizermos ObjectLoader uma classe, e src/geometries será abalada pela árvore.

Todos 88 comentários

Vou chamar dibs no resto da pasta de áudio 🔈

ei @mrdoob , você poderia esclarecer como você gostaria que tratássemos os scripts dentro da pasta de exemplos?

Estou gostando de #19989 indo direto para a conversão, mas percebo que, ao fazer isso, o utils/modularize.js não pode mais ser usado na pasta examples/js sem substituir esse trabalho. Isso marca o fim de mantermos o examples/js e o início de apenas examples/jsm ?

editar: ver comentário

Eu poderia trabalhar no resto da pasta math?

Eu poderia trabalhar no resto da pasta math?

Eu sou tudo para você dar-lhe um tiro. Lembro-me de tentar um tempo atrás, mas @Mugen87 acabou me repreendendo por isso. O resumo rápido disso foi um teste à medida que você avança, porque converter a pasta inteira de uma só vez pode estar se preparando para um passeio difícil. Uma parcial, ou mesmo arquivo por arquivo, seria bem vinda tenho certeza.

@DefinitelyMaybe vou ver o que mais pode ser migrado em src/animation/

legais. Acho que essa pasta está quase pronta. Pode ser apenas src/core/Object3D.js e src/core/BufferGeometry.js restantes?

Pode ser apenas src/core/Object3D.js e src/core/BufferGeometry.js restantes?

Sim, há muita classe ES5 que depende de Object3D e BufferGeometry .

Atire, houve algum progresso incrível nisso 🎉

Vou chamar a atenção em src/lights . Abriu src/extras e src/renderers na listagem acima, descobri que há algumas pastas em cada uma para trabalhar.

Olá a todos,

o que estávamos fazendo em relação a esse padrão?

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

é agora:

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

ou

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

atualmente, eu tenho feito o segundo, mas olhando para ele, eu diria que a intenção disso pode estar mais próxima do primeiro.

alguém sabe o que estava usando essas variáveis ​​em primeiro lugar?

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

☝️ Isso mesmo. isDirectionalLight é um bom exemplo, é usado assim:

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

Dito isso, pode haver ganhos de desempenho mantendo algumas propriedades do protótipo...

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

Talvez possamos revisá-los no PR caso a caso.

Vou tentar src/renderers/webgl 👍 👍

boa sorte se divirta. aquele tem um pouco acontecendo nele

Ei a todos, eu tenho src/renderers/webgl convertido. Foi louco. Vou continuar revisando tudo e esperar pelo #20039 antes de começar a empurrar os PRs.

👍
ansioso por isso

Percebi que @yomotsu usou getters somente leitura para propriedades is* no PR de matemática... Talvez seja o melhor!

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

hum pode ser. Eu sei que outros tentaram em alguns lugares tornar as variáveis ​​imutáveis. Isso parece um padrão bastante decente para mim.

caso de demonstração rápido do jsfiddle

Parece que este é o caminho a seguir:

foo.prototype.isDirectionalLight = true;

vou pesquisar src/objects . vou ver até onde posso chegar sem quebrar as coisas.

A pasta matemática acabou de ser concluída.
( As classes de interpolação são excluídas. )

Olá a todos,
Eu vou parar de trabalhar com src/objects , alguém é mais do que bem-vindo para pegá-lo nesse meio tempo.

Ei, bom trabalho com esses caras! 💪

Apenas um problema, foo.prototype.isDirectionalLight = true; não permite a vibração da árvore, já que a classe é modificada no local.
Também neste ponto eu sugiro fortemente não tocar mais no protótipo, já que estamos usando classes agora e o protótipo pode ser abstraído.

E esse padrão? Parece-me o mais explícito.

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

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

Há também a versão curta, que faz a mesma coisa, mas é um pouco mais implícita.

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

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

@marcofugaro a versão curta parece-me bem 👍

Ok, fez PR.

Além disso, acabei de notar que não podemos usar campos de classe porque estamos bloqueados por este PR .

Posso atualizar o pipeline de compilação para usar o mais popular @rollup/plugin-babel

Posso atualizar o pipeline de compilação para usar o mais popular @rollup/plugin-babel
e corrija esse problema se vocês quiserem.

Sim, seria ótimo se você pudesse fazer um PR 🙏

@marcofugaro , @mrdoob yay! sim por favor

Ei pessoal, aviso rápido que atualizei #20014 com Object.defineProperty e também corrigi a subclasse de AnimationClip . Se alguém tiver tempo para revisá-lo, agradeço o extra 👀 🙇 🙇

OK. Agora que r120 saiu... alguém poderia verificar se as coisas estão sendo sacudidas corretamente?

Parece que meio que funciona para mim, mas um pouco.
Não vejo mais ArrowHelper no meu arquivo de pacote com o webpack. mas muitos códigos desnecessários ainda existem😢

como sobre o tamanho do pacote? antes e depois

Olá pessoal, tive uma ideia e cravei uma ferramenta chamada shakediff . Você pode executá-lo assim:

$ shakediff builds/three.module.js Color

Isso gerará um pequeno módulo importando Color , agrupará com três e, em seguida, criará uma diferença de três a partir dos metadados do rollup. Você pode trabalhar com o diff detalhado ou simplesmente canalizá-lo para diffstat para obter o nível alto:

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

No momento não há pacote, mas você pode instalá-lo do meu repositório se quiser experimentá-lo. Feedback apreciado! ✌️

npm -g i ianpurvis/shakediff.git

ei @mrdoob , você poderia esclarecer como você gostaria que tratássemos os scripts dentro da pasta de exemplos?
Estou gostando do #19989 indo direto para a conversão, mas percebo que ao fazer isso o utils/modularize.js não pode mais ser usado na pasta exemplos/js sem sobrescrever esse trabalho. Isso marca o fim de mantermos os exemplos/js e o início de apenas exemplos/jsm?

Qual é o veredicto sobre este @mrdoob? Faria sentido tornar o jsm a fonte da verdade para que possamos converter exemplos em classes ES6? Talvez possamos fazer utils/demodularize.js para suportar a conversão na outra direção?

A pasta examples/js será removida em dezembro de 2020. Até lá, devemos deixar a pasta como está, sem atualizar seu conteúdo — ou os arquivos examples/jsm gerados a partir de seu conteúdo — para Classes ES6. Após essa data, os arquivos examples/jsm se tornarão a fonte da verdade e poderão ser atualizados para as Classes ES6.

Percebi que as variáveis ​​do escopo do módulo não estão sendo removidas durante a agitação. Você pode ver o comportamento com essas quatro vars, 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 devemos marcá-los como puros com o comentário especial-

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

Isso funciona para todos?

Parece-me bem 👌

Legal, isso exclui outras 144 linhas quando a árvore balança com Color 🥳

Por favor, todos dêem aos seus PRs abertos o tratamento /*@__PURE__*/ quando tiverem tempo!

@ianpurvis ótimo! você está usando o rollup, certo? poderia compartilhar sua configuração?

@mrdoob Finalmente consegui fazer alguns testes. Eu pessoalmente uso webpack, então fiz alguns testes com ele, minha configuração é essa se alguém se interessar .

testei esse código

import * as THREE from 'three'

console.log(THREE.WebGLRenderer)

0.119.1

0 119 1

0,120,1

0 120 1

Então, algo está sendo sacudido pela árvore, ótimo!

Olhando mais para isso, parece que a classe AudioListener não está no pacote, ótimas notícias!

Screenshot 2020-09-01 at 16 49 22

Screenshot 2020-09-01 at 16 50 07

O Webpack também remove automaticamente as variáveis ​​não utilizadas apontadas por @ianpurvis.


Depois disso, decidi testar métodos estáticos definidos fora da classe

Screenshot 2020-09-01 at 16 50 37

e, infelizmente, isso torna a classe não agitável

Screenshot 2020-09-01 at 16 51 04


Depois de fazer mais algumas escavações, notei que classes de geometria como DodecahedronGeometry , que não eram usadas em nenhum lugar, ainda estavam no pacote

Screenshot 2020-09-01 at 16 51 29

Screenshot 2020-09-01 at 16 52 08

Mais tarde eu descobri, isso era devido a este objeto Geometries three.module.js no pacote three.module.js

Screenshot 2020-09-01 at 17 18 32

Que é gerado automaticamente ao usar padrões como este no ObjectLoader . Isso provavelmente desaparecerá quando fizermos ObjectLoader uma classe, e src/geometries será abalada pela árvore.

@marcofugaro Sem problemas, aqui está a configuração de rollup

@marcofugaro Oi, adicionei suporte ao webpack ao shakediff... essa configuração do webpack parece boa para você? Como o terser é responsável pela eliminação de código morto na vibração da árvore do webpack, é difícil evitar alguns artefatos de transformação nessas saídas. Mas se você diferenciar usando um algoritmo de histograma com espaços em branco desativados, é gerenciável. De um teste rápido hoje à noite, o webpack parece aceitar /*@__PURE__*/ e /*#__PURE__*/ . Acho que podemos padronizar um ou outro. Mais amanhã...

@ianpurvis Acho que não tenho permissão para instalar shakediff na minha máquina...

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

De qualquer forma, fiz um teste simples:

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

E notei que Geometry não estava sendo sacudido pela árvore. https://github.com/mrdoob/three.js/pull/20394 corrige.

Tentei então fazer:

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

E notei que o rollup não abala métodos não utilizados... 😕

@mrdoob infelizmente, no futuro previsível, os métodos de classe nunca serão abaláveis ​​por nenhuma ferramenta. Caramba, eles não podem nem ser reduzidos!

Isso ocorre porque em javascript, você pode acessar métodos como this['I am a string'] , assim como você pode acessar propriedades de objetos dinamicamente. Por esta razão, as ferramentas não sabem de antemão se e como você vai chamar um método (pode ser this[variable] ).

Isso é o mesmo para as classes ES6 e classes de função. Por exemplo, em three.min.js , os métodos são deixados intocados, assim como qualquer propriedade de objeto 🙂

E ninguém propôs um modo "estrito" do construtor, onde se espera que você não chame métodos como this['I am a string'] ?

Não faço ideia 🤷‍♂️

Aqui está uma discussão sobre este tópico sobre rollup: https://github.com/rollup/rollup/issues/349

métodos de classe nunca serão abaláveis ​​por nenhuma ferramenta. Caramba, eles não podem nem ser reduzidos!

Desculpe por sair do tópico, mas você pode fazer a minificação funcionar se você der ao compilador alguma dica sobre o que é "público" versus "privado". No passado, usei prefixos "_" em métodos para isso. Consulte https://github.com/developit/microbundle/wiki/mangle.json. Mas, infelizmente, também não tenho ideia se algo semelhante é possível para sacudir as árvores. 😕

Uau! #20395 mesclado! coisa boa @marcofugaro

Notícia incrível sobre babel e geometria!

@ianpurvis Acho que não tenho permissão para instalar o shakediff na minha máquina...

@mrdoob Hm, parece que o Parcel tem uma dependência dessa versão do fsevents ... talvez eu possa fixar isso em algo maior.

Fyi, boas informações aqui sobre melhorias de trepidação de árvores no Webpack 5 ...

Fyi, boas informações aqui sobre melhorias de trepidação de árvores no Webpack 5 ...

Progresso... Espero que o Rollup implemente isso também...

Olá a todos,

Quais são os objetivos da propriedade .is**Classname** e this.type = **Classname** exatamente?
Não é um resto do antigo padrão de pseudo classe?
Por que não se livrar totalmente dele e substituir esse uso pela maneira normal de verificação de tipo?

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

Quero dizer, como parte da mudança para classes ES, os objetos terão tipos corretos já verificáveis...

A biblioteca usava obj instanceof Vector3 antes.
Mas Rich Harris implementou e alterou todas as verificações para is* para permitir a agitação da árvore: #9310

A biblioteca usava obj instanceof Vector3 antes.
Mas Rich Harris implementou e alterou todas as verificações para is* para permitir a agitação da árvore: #9310

Obrigado pela resposta, eu li o tópico, aliás, não entendo por que uma classe deve ser evitada para estar na saída se alguma outra classe precisar verificar o tipo ... estar ciente de que um objeto é uma classe B, então a classe B é usada (pelo menos para criar o referido objeto de alguma forma) e tem que ser empacotada, não é?

Por exemplo, o WebGLRenderer precisa verificar se uma geometria que ele renderiza é BufferGeometry ou Geometry, mas nunca cria instâncias de Geometry. A maioria dos aplicativos three.js deve usar apenas BufferGeometry e, portanto, queremos que o tree-shaking elimine Geometry (e suas subclasses) do pacote quando possível.

De forma visual...

Esse padrão faz com que WebGLRenderer sempre inclua Geometry ao agrupar:

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

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

Este padrão não:

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

Olá a todos,

dado isso , quais são nossos pensamentos sobre seguir em frente a partir daqui?

Acho que ainda não houve mudança. Qualquer coisa que (1) não esteja em examples/js e (2) não seja estendida por algo em examples/js pode ser convertida em Classes ES6. Se esse processo estiver terminando, devemos decidir quando começar a mudar examples/js para classes.

De memória, e depois de uma rápida olhada, fizemos um bom bocado e ainda há alguns PRs prontos esperando.

Eu posso tentar recompilar minha lista de dependências/extended-in-examples.

@DefinitelyTalvez Ei! Isso parece ótimo, sua lista foi super útil. E a estratégia do @donmccurdy faz sentido para mim. 👍 Acho que seria melhor encerrar o trabalho que já fizemos. #20070 seria um ótimo PR para atacar porque pode dar estratégia para migrar vars privados/ocultos para ES6 (precisamos disso para migração de renderers/webgl para ES6). Se todos puderem executar os benchmarks ou participar da discussão, eu agradeceria. Acho que temos algumas opções decentes, só precisamos garantir que o desempenho seja bom.

OK,
Eu posso começar algumas relações públicas para exemplos de reescrever para classes ES ...
@mrdoob é um problema para você fazer o script jsm para js ou não? (Acho que não, mas me diga se prefere que esperemos)

Antes de converter o código de exemplo em classes, #20527, #20529 ou uma solução diferente deve ser mesclada primeiro. Exceto para o código que atende às condições mencionadas em https://github.com/mrdoob/three.js/issues/19986#issuecomment -718308451.

@DefinitelyMaybe Você disse no primeiro comentário :

  • usar campos de classe

1) Isso significa que podemos usar campos de classe para tudo?
Igual a :

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 é apenas para propriedade .is* ?

Então, 2) e quanto aos construtores vazios? A especificação ES2015 disse que os construtores com apenas uma chamada super() são implícitos se não forem fornecidos, portanto, algumas classes filhas podem ser realmente definidas mais facilmente:

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

}

E 3) e os campos de classe 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 )
    }

}

O Chrome mais recente oferece suporte nativo a campos de classe pública e privada agora...

20395

A primeira chave é passar em todos os testes.

Você terá menos problemas inicialmente mudando menos.

@marcofugaro Acredito que ainda existam algumas variáveis ​​que podem ser alteradas em campos de classe, certo?
Estou olhando coisas como:

class EdgesGeometry extends BufferGeometry {

    constructor( geometry, thresholdAngle ) {

        super();

        this.type = 'EdgesGeometry';

alterado para:

class EdgesGeometry extends BufferGeometry {

    type = 'EdgesGeometry';

    constructor( geometry, thresholdAngle ) {

        super();

É provável que encontremos outras ressalvas ao redor do local, como como encontrei " new this.contructor() != new Foo() ".

campos de classe privada

essa é uma discussão em andamento. Vai demorar um pouco antes de usá-lo, se o usarmos. Não tenho certeza de um problema ou PR que eu possa apontar para você.

@marcofugaro Acredito que ainda existam algumas variáveis ​​que podem ser alteradas em campos de classe, certo?
Estou olhando coisas como:

Sim, isso pode ser feito agora. No entanto, não podemos fazer isso para propriedades .is* , pois elas precisam ser não enumeráveis ​​e não graváveis, para aquelas temos que usar Object.defineProperty(this, ... .

como é verificado novamente? seria possível usarmos a palavra-chave static em vez de Object.defineProperty(this, ... ?

como é verificado novamente? seria possível usarmos a palavra-chave static em vez de Object.defineProperty(this, ... ?

Acho que não, porque obj.is* tem que estar em instâncias, não na própria classe...

Não tenho certeza do que o babel transpila exatamente na configuração atual, mas podemos usar decoradores para definir um campo de classe como não enumerável/não gravável:

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

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

@DefinitelyMaybe static propriedades são diferentes, elas não são acessíveis a partir da instância, mas sim da própria classe.

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


Edit: não importa o que eu estava dizendo...
sim Sim.

Meu ponto principal é que, se fôssemos ajustar o código que verifica essa propriedade, poderíamos ir de:

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

para

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

Então, eu queria saber onde e por que essa verificação ocorre e se podemos ou não alterá-la.

@DefinitelyMaybe O problema é obter as informações de um tipo de instância. Então, se você pudesse acessar a classe da instância para obter sua prop estática, por que ter uma prop estática? Você já tem o nome da classe...

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

Edit: escrevendo isso, pude descobrir que ter vários .is * pode ser útil para testar em cada cadeia de herança finalmente, em comparação com apenas o único nome de classe final ...

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

Edit2: sim também o mesmo pode ser alcançado com nomes de classes finalmente, mas mais complicado de testar ...

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

da instância

opa. releia aquele. sim, não importa o que eu estava dizendo.

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

direito. Duas coisas.

  • O que nos resta?

devemos decidir quando começar a mudar examples/js para as aulas.

  • Aproximando-se da necessidade de discutir isso para progredir.

Não sei se devemos esperar por #20527 ou #20529 porque ambos estarão tentando recriar o examples/js em sua forma atual, que não é onde estamos buscando. Minha sugestão inicial é começar a converter examples/js como está. A questão é, que problemas estamos enfrentando...

Eu também queria reiterar algo que @mrdoob disse recentemente

Eu odiaria forçar os novatos a aprender sobre polyfills ou bundlers para renderizar seu primeiro cubo.

Como alguém que tem trabalhado com módulos nos últimos tempos, o fluxo de trabalho é claro e eu entendo os vários conceitos necessários para que algo funcione. Não precisamos de bundlers e polyfills, mas precisaremos ajustar como Three.js é descrito inicialmente .

Além disso, talvez a adição de um REPL mas voltado para Three.js, possa ajudar nessa área? Um exemplo sendo o Svelte

Também precisaremos esclarecer como substituir alguns padrões que não são de classe, como:

function Foo() {

    this.update = function () {

        var priv = 'foo'

        return function update() {
            ...
        };

    }();

}

IMHO, poderíamos usar campos de classe privada e fazer o rollup/babel transpile para o padrão antigo para certos navegadores antigos que não implementam isso nativamente ...

IMHO, poderíamos usar campos de classe privada e fazer o rollup/babel transpile para o padrão antigo para certos navegadores antigos que não implementam isso nativamente ...

Eu concordo com essa estratégia, mas a decisão obviamente depende dos mantenedores principais que precisarão manter esse código.

legal. Pode ser uma ideia mostrar isso dentro de src primeiro, ou seja, encontrar um padrão similarmente estranho ao que @devingfx descreveu em src , faça um PR que use variáveis ​​privadas e mostre o que o babel faz com isso.

alguma sugestão de qual script?

buscas: internal , private , readonly 👀

espere, todas as variáveis _* deveriam ser privadas?

...

Um elefante nesta sala pode ser src/renderers/WebGLRenderer.js

Que tal WebGLAnimation, é uma classe pequena e agradável... https://github.com/mrdoob/three.js/pull/20070

alguma sugestão de qual script?

Estou focado em exemples/js e encontrei isso no OrbitControls...

mostre o que babel faz com isso.

Tenho certeza de que não produzirá algo que corresponda ao pensamento de sintaxe do mrDoob 😅

para a direita.

e opa. Onde está meu cérebro... precisaremos de um de #20527 ou #20529 (ou outro) para mesclar para começar a transformar a pasta examples . examples/js está por perto no futuro próximo, o que significa que tocar a pasta examples/js com classes é um absoluto não, não. isso quebraria a compatibilidade com o IE... suspiro.

faça o rollup/babel transpile para o padrão antigo

Adivinha o seu pensamento e apoio esses JSM para JS PR's. Podemos mirar no examples/jsm assim que uma decisão for tomada.

Adicionar variáveis ​​privadas em src ainda é uma boa ideia, pois seria uma boa solução para o problema de longa data de "por favor, não brinque com essas variáveis, elas têm um propósito específico"

tocar na pasta examples/js com classes é um absoluto não, não.

Ooops, meu mal, eu estava falando sobre cavar exemples/jsm é claro, exemples/js será a versão "construída" em um futuro próximo ...

isso quebraria a compatibilidade com o IE... suspiro.

O que??? Ainda estamos falando sobre o Internet Explorer em 2020? Estamos falando sobre a compatibilidade de uma biblioteca WebGL neste dinossauro de 7 anos? A sério !! 1,4% ...
_(devemos adicionar um coletor de estatísticas na lib para coletar se algum usuário TRÊS estiver planejando um uso no IE)_

😞 Aliás, é por isso que a babel existe...

Os arquivos de compilação three.js e three.min.js , bem como todos os arquivos em examples/js , ainda devem suportar navegadores mais antigos, como o IE 11.

Houve um PR no ano passado que deveria interromper o suporte para o IE 11 (#18091), mas descobriu-se que ainda existem usuários confiando neste navegador. E a política atual do projeto é fornecer os respectivos arquivos para o usuário para que ele não realize a conversão de ES6 para ES5 sozinho. Isso também foi discutido em #20455.

a política atual do projeto é fornecer os respectivos arquivos para o usuário para que ele não realize a conversão de ES6 para ES5 sozinho.

Ok, não há problemas com essa política se a fonte puder ser desenvolvida de maneira moderna e se as compilações resultantes não forem legíveis, mas apenas funcionando ...
Porque os transpiladores produzem um código tão feio!
Portanto, não vejo problemas para src ser escrito em ESnext, e as compilações serem feias, MAS é um problema potencial com exemples/js se esses arquivos devem ser legíveis, comentados e bem formados ...

BTW eu estou me perguntando por várias vezes por que alguns exemplos são exemplos e não fontes principais do núcleo!?
Exemplo: os controles geralmente são usados ​​como estão, copiados como complementos opcionais e não usados ​​como um exemplo real que você lê e se inspira para escrever seus projetos, como um exemplo de cubo giratório por exemplo...

_(Comecei minha jornada com THREE por uma pesquisa: "webgl rotary cube" e um exemplo disso levando a uma maratona de códigos de 1 noite desenvolvendo um pequeno jogo com um cubo se movendo em plataformas ^^)_

Ao usar uma compilação adequada, não importa quais arquivos estão no núcleo e quais estão no diretório de exemplos. Contanto que a vibração da árvore funcione corretamente, você só terá os arquivos de origem em sua compilação que são realmente necessários.

Para mim, a distinção entre núcleo e exemplos vem de uma época em que esse tipo de fluxo de trabalho ainda não estava disponível. O núcleo deve ser pequeno e compacto, pois você teve que importá-lo completamente como um único componente. Apenas os arquivos mais _importantes_ devem ser incluídos. Quais arquivos acabaram no núcleo foi, em certo sentido, uma decisão caso a caso.

Ao usar uma compilação adequada, não importa quais arquivos estão no núcleo e quais estão no diretório de exemplos. Contanto que a vibração da árvore funcione corretamente, você só terá os arquivos de origem em sua compilação que são realmente necessários.

Isso é verdade apenas para usuários de módulos ES ;)

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Horray picture Horray  ·  3Comentários

clawconduce picture clawconduce  ·  3Comentários

Bandit picture Bandit  ·  3Comentários

yqrashawn picture yqrashawn  ·  3Comentários

filharvey picture filharvey  ·  3Comentários