Three.js: Avalie o TypeScript

Criado em 8 jan. 2019  ·  28Comentários  ·  Fonte: mrdoob/three.js

Avalie o TypeScript

Usei o modelo do RFC Ember.js para documentar esse problema. Acho que é um bom modelo para abordar as principais preocupações sobre uma mudança maior. Para obter detalhes sobre o processo de RFC, você pode visitar o repositório github: https://github.com/emberjs/rfcs

Resumo

Eu queria mover todas as discussões do TypeScript em um único lugar, porque agora todos os prós e contras sobre o TypeScript estão espalhados por vários problemas, threads, solicitações de pull e discussões. Isso torna muito difícil acompanhar e acho que não haverá nenhum progresso significativo se não nos concentrarmos. Além disso, acho que há muita tração em relação a three.js e TypeScript, como visto recentemente em https://github.com/mrdoob/three.js/issues/11552

Motivação

Como o TypeScript se torna cada vez mais popular na comunidade de front-end, podemos começar a pensar sobre a adoção. Além disso, se você comparar os downloads semanais de @types/three e o pacote three no npm, parece que muitas pessoas já usam o Three.js com o TypeScript. Para o período de 01/01/2019 a 07/01/2019, foram 56414 downloads de three e 40588 de @types/three (para mais detalhes, consulte: https://www.npmjs.com / package / @ types / three e https://www.npmjs.com/package/three). Além disso, já existe muito trabalho realizado em vários projetos e repositórios. Portanto, seria bom unir forças e manter o material do TypeScript em um só lugar.

Na minha opinião, existem mais prós do que contras para o TypeScript (mas é claro que existem muitas opiniões controversas sobre os tipos em JavaScript e TypeScript, em especial na comunidade)

Alguns dos profissionais que vejo são:

  • possibilidade de melhorar a experiência do desenvolvedor, também para novos colaboradores e para usuários da biblioteca Three
  • tipos podem ajudar a explorar a API da biblioteca Três e podem ajudar a desenvolver com menos necessidade de ler os documentos
  • nenhuma definição desatualizada de @types/three
  • espaço para futuras otimizações de transpile (por exemplo, coisas como tsickle estão funcionando direito, acho que haverá mais ferramentas como esta no futuro). Além disso, ferramentas experimentais como o AssemblyScript podem se tornar uma opção para certas partes críticas de desempenho do código-fonte
  • tipos podem ajudar a melhorar a qualidade do código
  • possibilidade de usar novos recursos do padrão ECMAScript e transpilar a fonte para diferentes versões do ECMAScript
  • quando bem feito, não faz diferença para os usuários da biblioteca Three se o código-fonte é mantido em TS ou JS
  • com o sinalizador do compilador declarationDir somos capazes de gerar os d.ts arquivos de nosso código-fonte para que todas as digitações estejam sempre atualizadas

Projeto detalhado

Devemos terminar todos os esforços do ES6 primeiro, pois eles formam a base do TypeScript. Além disso, a transição do ES6 para o TypeScript não seria tão difícil (já que o TypeScript se parece muito com o JavaScript moderno com tipos). Para começar com o TypeScript, precisamos apenas adicionar rollup-plugin-typescript (eu sugeriria rollup-plugin-typescript2 ). Em seguida, precisamos criar um tsconfig.json e configurar todas as configurações do compilador TypeScript de acordo com nossas necessidades. Talvez devêssemos adicionar tslint também (há também um plugin de rollup para isso, é chamado rollup-plugin-tslint ). Após os trabalhos de construção, poderíamos incorporar as tipificações feitas em @types/three e outros projetos como three.ts .

Como ensinamos isso

No início, precisaríamos documentá-lo corretamente para novos contribuidores. Para os usuários do Three.js, tudo permanece o mesmo (já que o TypeScript é transpilado para o JavaScript). Depois de algumas iterações, faria sentido fornecer os exemplos de código nos documentos em TypeScript e JavaScript. Um bom exemplo de como isso pode ser feito é a documentação da API Stripe

Inconvenientes

O pipeline de construção se torna mais complicado e mais dependências são adicionadas. Além disso, não tenho certeza de como é fácil migrar o conjunto de testes e o executor de teste. Além disso, a barreira de entrada para novos colaboradores (não para usuários da biblioteca) pode se tornar maior, pois eles precisam conhecer o TypeScript. Um código muito genérico pode se tornar muito prolixo ao adicionar tipos. Com o TypeScript, estamos um pouco mais distantes da "plataforma", pois há uma etapa de transpilação no meio e não temos controle total da transpilação (é claro que poderíamos escrever nossas próprias transformações, mas isso é muito tedioso)

Alternativas

Apenas fique com o JavaScript puro, mas isso também significa que negligenciamos todos os esforços já feitos por projetos como @types/three . Para todos os usuários de Three.js com TypeScript, isso significaria que eles precisam confiar em uma tipagem não oficial de Three.

Questões não resolvidas

  • Nós realmente queremos isso?
  • Quando começar (agora ou após a finalização do ES6)?
  • Como começar? Devemos começar no início apenas com d.ts arquivos ou pular totalmente para o TypeScript?
  • Quem poderia fazer isso ou me deixe formular de outra forma, quem está motivado para começar isso?

Comentários muito úteis

Até que os navegadores não ofereçam suporte nativo ao TypeScript, prefiro focar no JavaScript ES6.

Eu entendo que pode ser compilado para .js, mas estamos apenas começando a importar do src diretamente e acho que isso vai ajudar o projeto mais do que a conversão para TypeScript.

https://github.com/mrdoob/three.js/blob/dev/examples/webgl2_sandbox.html#L37 -L48

Adicionar arquivos * .d.ts lado a lado parece bom, mas será necessário que alguém os possua e os mantenha atualizados.

Todos 28 comentários

Do ponto de vista do desempenho do tempo de execução, estou interessado em

Além disso, ferramentas experimentais como o AssemblyScript podem se tornar uma opção para certas partes críticas de desempenho do código-fonte

Tenho feito experimentos Three.js core + WASM.

https://github.com/takahirox/three.wasm-experimental
https://twitter.com/superhoge/status/1071132448426262529

A partir da experimentação, percebi que portar todo o núcleo para WASM pode melhorar o desempenho do tempo de execução, 1,5x mais rápido no meu exemplo, enquanto portando parcialmente as partes pequenas, por exemplo apenas códigos matemáticos (Vector3, Matrix4, ...), não é nenhum benefício porque de grande sobrecarga JS-WASM.

Mas não achei uma boa ideia reescrever todo o núcleo do Three.js em C ++ ou Rust para os contribuidores devido à dificuldade de manutenção, então estou procurando maneiras alternativas. Estou interessado em saber se TypeScript + AssemblyScript funciona bem para Three.js.

Como começar? Devemos começar no início apenas com arquivos d.ts ou pular totalmente para o TypeScript?

Estaremos enviando um PR que adiciona arquivos * .d.ts ao Three.JS, com base principalmente em @ types / three (reutilizando esse trabalho). Esse é um ótimo ponto de partida e nos permite continuar em JS por enquanto. Também pode ser feito de forma incremental.

@takahirox bom trabalho :-) Estou sempre fascinado com a quantidade de trabalho inovador que acontece em torno do Three.js. É uma pena que essas provas de conceito recebam tão menos atenção. Também acho que reescrever tudo em C ++ ou Rust não é uma opção. Talvez o AssemblyScript seja, mas não experimentei o AssemblyScript, então posso apenas falar sobre o que li sobre o AssemblyScript. Mas talvez devêssemos considerar o AssemblyScript também porque, pelo que entendi, é mais ou menos um subconjunto do TypeScript

@bhouston Não tenho certeza se mover os arquivos d.ts de @types/three para o repo three faz muito sentido. Principalmente porque esses d.ts arquivos podem ser gerados a partir de arquivos TypeScript e estão sempre sincronizados. Existe uma maneira de garantir que os arquivos d.ts estejam sempre sincronizados com os arquivos js de forma automatizada? Se sim, eu acho que colocar os d.ts arquivos no three repo pode ser benéfico. Também acho que depende da decisão dos mantenedores. Se eles não quiserem adotar o TypeScript, os arquivos d.ts podem ser uma opção. Além disso, se eles decidissem adicionar o TypeScript em alguns anos, poderíamos transpor esse tempo com arquivos d.ts . Caso contrário, temo que haja menos benefícios e mais trabalho. Mas talvez eu esteja apenas negligenciando algo

@bhouston Não tenho certeza se mover os arquivos d.ts de @ types / three para o repo três faz muito sentido. Principalmente porque esses arquivos d.ts podem ser gerados a partir dos arquivos TypeScript e, portanto, estão sempre sincronizados.

Se movermos diretamente para o TypeScript, não haverá necessidade de arquivos * .d.ts. O problema é que atualmente o projeto @ types / three está sempre um pouco desatualizado com o Three.JS porque é mantido separadamente. Além disso, ele reflete a estrutura construída de three.js ao invés de arquivos individuais e, portanto, não pode suportar trepidação de árvore e outras formas de otimização. Assim, adicionar arquivos * .d.ts melhora muito o projeto de seu estado atual, mas não é tão bom quanto mover para arquivos * .ts diretamente.

Se pudermos ir diretamente para os arquivos * .ts, essa é a melhor opção. Eu não tinha certeza se havia suporte para isso.

Eu entendo que o Three.JS gosta de fazer as coisas de forma incremental, portanto, essa foi uma opção incremental, em vez de um big bang.

@bhouston concordo totalmente com você. E também acho que uma reescrita big bang não é possível, então precisamos adotar de forma incremental. Mas se eu ler os documentos do TypeScript, parece que poderíamos ter os arquivos ts e js lado a lado. Assim, poderíamos começar a converter arquivos individuais em ts. Para obter mais detalhes, você pode ler esta postagem do blog: https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html

Mas como abordar o TypeScript deve ser decidido por um dos mantenedores. Acho que ambas as opções ( d.ts arquivos ou misturar arquivos ts e js) são viáveis. E é mais ou menos uma questão de preferências pessoais e estilo.

@tschoartschi Eu gostaria de avançar com este problema. @mrdoob aprovou arquivos * .d.ts lado a lado. Eu gostaria de ir lá porque não força o TypeScript às pessoas imediatamente e podemos desistir dele sem ter que reescrever todas as contribuições durante a fase * .ts. E então ainda podemos converter arquivos * .js em arquivos * .ts de forma incremental, principalmente ao mesclá-los com os arquivos * .d.ts lado a lado.

Acho que os arquivos * .d.ts lado a lado são um primeiro passo muito bom e fácil de fazer. Eu preferiria não permitir que a "perfeição" nos impedisse de fazer progressos incrementais.

@bhouston cool 😎 Eu também poderia ajudar. Acho que faria sentido que você comece e outros e eu possamos participar. Talvez possamos falar também com os mantenedores de @types/three . Devemos criar um canal Slack no espaço de trabalho Three.js? Portanto, podemos nos alinhar mais rapidamente e não poluir esse problema com conversas semelhantes a um bate-papo. No entanto, eu esperaria um momento até que @mrdoob acrescente seu ponto de vista. Porque se ele é contra o TypeScript, acho que não devemos investir tempo.

Estou disposto a dedicar tempo ao port assim que receber a aprovação de @mrdoob.

Até que os navegadores não ofereçam suporte nativo ao TypeScript, prefiro focar no JavaScript ES6.

Eu entendo que pode ser compilado para .js, mas estamos apenas começando a importar do src diretamente e acho que isso vai ajudar o projeto mais do que a conversão para TypeScript.

https://github.com/mrdoob/three.js/blob/dev/examples/webgl2_sandbox.html#L37 -L48

Adicionar arquivos * .d.ts lado a lado parece bom, mas será necessário que alguém os possua e os mantenha atualizados.

@mrdoob Não acho que esperar que os navegadores ofereçam suporte ao TypeScript seja uma opção. Não ouvi nenhuma intenção de nenhum fornecedor de navegador de implementar o TypeScript. Mas vejo sua preocupação, principalmente com os exemplos. Não dei uma olhada nos novos exemplos. É incrível que seja possível apenas importar os arquivos fonte dos exemplos.

Não tenho certeza de qual seria a melhor solução para criar a biblioteca em TypeScript e ainda manter a possibilidade de importar JavaScript do src. Claro, poderíamos transpilar os arquivos TypeScript e, em seguida, ter o arquivo JavaScript correspondente lado a lado (que é a configuração padrão do compilador TypeScript), mas isso poderia complicar coisas como controle de versão de código etc.

three/
├── src/
    ├── cameras
        ├── PerspectiveCamera.ts // authored code
        ├── PerspectiveCamera.js // generated code by TS compiler

No entanto, isso parece um pouco estranho para mim, já que o código transpilado deve ir para algum lugar em uma pasta dist , build ou bin . Mas isso é apenas uma opinião, não um fato concreto. Talvez haja alguns geeks do TypeScript que conheçam uma solução melhor.

A outra opção é o arquivo d.ts sugerido por @bhouston. Mas, como @mrdoob mencionou, pode ser complicado manter os arquivos d.ts atualizados. Especialmente em uma visão de longo prazo. É realmente administrável mantê-los atualizados nos próximos anos? Eu poderia ajudar a configurar os arquivos d.ts mas não posso garantir que estarei envolvido em atualizá-los o tempo todo. Para mim, é muito mais difícil comprometer o tempo continuamente do que bloquear um intervalo único e fazer algumas coisas. Ainda não tenho certeza se é melhor apoiar o projeto @types/three ou adicionar d.ts arquivos diretamente no projeto three . O projeto @types/three já está funcionando e atende às mesmas necessidades da abordagem d.ts . Ele também tem desafios semelhantes. O que é basicamente manter as coisas atualizadas.

Portanto, minha conclusão é que não parece muito bom para o TypeScript em Three.js no futuro de médio prazo. Para mim, tudo bem, embora eu adorasse ver mais adoção do TypeScript.

Apenas outra sugestão:
A estrutura do jogo Phaser usa seus comentários para gerar definições de tipo automaticamente. Acho que a ferramenta é de código aberto. Portanto, as definições de TS podem ser geradas adicionando / ** comentários * / acima das funções da maneira correta.

A estrutura do jogo Phaser usa seus comentários para gerar automaticamente definições de tipo ...

Consulte https://github.com/mrdoob/three.js/issues/11550 e https://github.com/mrdoob/three.js/issues/4725#issuecomment -41833647.

Embora, gerar documentação a partir de comentários em arquivos *.d.ts possa ser interessante. 🤔

Adicionar arquivos * .d.ts lado a lado parece bom, mas será necessário que alguém os possua e os mantenha atualizados.

Se as digitações podem ser verificadas em relação ao código-fonte programaticamente, estou bem com isso. Do contrário, e se não estivermos planejando reescrever a base de código no TypeScript, não acho uma boa ideia mover as digitações para o repositório. De qualquer forma, estamos menos preparados para mantê-los aqui - pelo menos os atuais mantenedores estão usando o TypeScript.

Existe também este projeto https://github.com/semleti/three.ts
Vale a pena dar uma olhada e trazê-lo para a v100 em vez de começar uma nova?
Porque eu não vejo Three.js sendo reescrito em TypeScript, a menos que seja óbvio o quão melhor é trabalhar com tipos para um projeto tão grande ... E eu entendo perfeitamente por que isso pode nunca acontecer, já que dependeria de uma linguagem isso não é padrão no navegador.

@schoening Comecei esta discussão porque existem algumas versões de TypeScript de prova de conceito de Three.js por aí. É o repo que você vinculou ou o repo feito por @flyover (https://github.com/flyover/three.ts, https://github.com/mrdoob/three.js/issues/11552#issuecomment-367026821) . O principal problema com uma versão bifurcada do Three.ts é manter-se atualizado. Todos os repos estão algumas versões atrás e acho que isso acontecerá com todos os projetos que não são mantidos pela equipe "principal". Se o projeto Three.js não for compatível com TypeScript, acho melhor ajudar o projeto @ types / three a permanecer em sincronia. Acho que devemos unir forças lá.

Se Three.js for oferecer suporte a TypeScript em algum momento no futuro distante, seria ótimo pensar como essa transição poderia ter sucesso. Como @donmccurdy mencionou, existem várias abordagens para obter uma melhor compatibilidade do TypeScript. Acho que o JSDoc pode ser uma abordagem viável. Ainda não estou convencido com os arquivos *.d.ts pois acho que é ainda mais difícil mantê-los atualizados do que os comentários JSDoc. Além disso, não acho que haja uma maneira de verificar o código-fonte programaticamente com arquivos *.d.ts . Mas talvez @bhouston pudesse delinear sua abordagem, especialmente as preocupações em manter as coisas atualizadas. Talvez existam algumas soluções inteligentes para esse problema.

A melhor experiência para mim até agora é vscode + d.ts + JSDoc, tudo no mesmo projeto, por isso é fácil ficar em sincronia.

A versão mais recente do vscode melhorou o suporte de checkJs (pode ser habilitado em tsconfig.json ), que basicamente é o compilador TypeScript verificando arquivos JavaScript, usando os tipos de JSDoc mais a declaração de d.ts para os tipos mais "avançados", o que seria feio na sintaxe JSDoc.

Visto que o vscode pode derivar todos os tipos, ele pode detectar todos os tipos de erros de tipo também, então sempre que a refatoração é feita, é fácil ver e editar os tipos "bugados / antigos" de d.ts , então ele continua sendo sincronizado .

A pior coisa sobre o TypeScript é a etapa de transpilação extra, que pode levar alguns segundos para cada alteração de código. Resumindo, JSDoc + d.ts em vscode tem todas as vantagens dos tipos, mas não a desvantagem da etapa de transpilação lenta extra.

O único problema é adicionar o tipo JSDoc 100% adequado a tudo, para que o vscode possa confiar nele (apenas coisas como @constructor , <strong i="16">@enum</strong> {number} , <strong i="18">@param</strong> {number} n Number of steps )

Também gostaria de acrescentar aqui que @bhouston e @LuWangThreekit criaram um PR para *.d.ts arquivos. Para obter mais detalhes, verifique sua nota: https://github.com/mrdoob/three.js/issues/11552#issuecomment -454881060 e / ou seu PR https://github.com/mrdoob/three.js/pull/ 15597

Nota secundária: TypeScript em navegadores pode não estar muito longe se Deno (um interpretador TypeScript construído em V8 e Rust com 32.000 estrelas no GitHub) provar ser digno.

Uma vez que adicionamos arquivos de declaração de tipo para o núcleo e os módulos de exemplo, acho que não há problema em encerrar o problema por enquanto. A experiência de desenvolvimento para usuários de TS deve ser definitivamente melhor do que no ano passado.

Para qualquer pessoa interessada em TypeScript ...

Esta biblioteca inspirada em Three.js que @bhouston está trabalhando pode ser o que você está procurando:

https://threeify.org/

Threeify de @bhouston parece um ótimo projeto 🤩 tem SemVer e usa liberação semântica. É construído em cima do TypeScript e seus valores centrais parecem ser coisas como Tree Shaking, Small Build Files etc. Todas coisas que muitos de nós gostariam de ver em Three.js também. Eu realmente valorizo ​​o trabalho que vai para o Threeify 👍

@bhouston @mrdoob Mas é mesmo necessário criar um novo projeto? Faz sentido dividir a comunidade? Muitos dos grandes frameworks de front-end conseguiram fazer a transição para coisas como SemVer, TypeScript, Tree Shaking etc sem uma bifurcação de seu código e comunidade.

Acho que @pailhead escreveu um artigo interessante sobre como trabalhar com Three.js, acho que foi o seguinte: Trabalhar com diferentes versões do three.js . Acho que há pessoas na comunidade que gostariam de ajudar a adotar algumas das coisas que o Threeify tenta implementar. Acho que seria ótimo unir forças e melhorar o Three.js em vez de criar uma nova biblioteca.

Como muitos artigos na Internet, o artigo de Pailhead é tendencioso. Não leva em consideração outros usos da biblioteca.

Não acho que seja possível fazer uma biblioteca que atenda a todos os tipos de desenvolvedores js sem interromper o fluxo de trabalho de desenvolvimento uns dos outros.

Temos experiências muito semelhantes às de @pailhead . Não acho que seu fluxo de trabalho seja um fluxo de trabalho de nicho. Acho que seu fluxo de trabalho é muito comum para desenvolvedores que trabalham com frameworks front-end modernos como Vue , Ember , React , Svelte , Angular ...

Talvez devêssemos dar uma olhada em como Vue está fazendo isso. Ele tem uma base de usuários que vai desde programadores de PHP que desejam apenas aprimorar seu site até pessoas que desenvolvem aplicativos da web sofisticados. Isso curva muito bem a curva entre esses diferentes tipos de usuários.

Também sobre como atualizar a base de código existente sem prejudicar a experiência de todos, há ótimos exemplos por aí. Poderíamos dar uma olhada em como o Ember conseguiu crescer de forma consistente com a comunidade da web e seus padrões da indústria.

Eu não consideraria ficar atualizado com o desenvolvimento moderno da web inviável. Mas eu concordo totalmente que é um grande esforço e precisamos pensar muito sobre essas coisas. É por isso que acredito que é melhor trabalharmos juntos para criar uma experiência moderna do que criar vários novos projetos.

Quando você passar por este tópico, já existem dois projetos diferentes, Three.ts e Threeify e provavelmente muitos mais por aí. Eu realmente acredito que haveria um grande benefício para toda a comunidade Three.js se trabalhássemos juntos em vez de criarmos iniciativas separadas.

@mrdoob , que tal uma pesquisa para coletar alguns dados? o uso de texto datilografado é uma coisa e tenho certeza de que existem outras variáveis ​​qualitativas sobre as quais poderíamos tentar obter uma estimativa.

@ roomle-build você pode listar as desvantagens de converter a biblioteca para TypeScript?

Não vejo uma desvantagem real em adotar gradualmente o TypeScript para a biblioteca. Em contraste, acho que traria muitos benefícios (é por isso que muitos projetos estão convertendo para TypeScript). No entanto, existem alguns desafios, é claro, por exemplo:

  • como podemos fornecer uma experiência agradável para nenhum usuário do TS?
  • como os usuários sem uma etapa integrada podem usar a biblioteca
  • e, claro, todas as outras coisas em que não pensei

Mas como eu disse antes, essas questões foram resolvidas em outros projetos também e podemos copiar essas soluções de lá (como Vue ou Ember por exemplo).

Mas o principal que eu queria ressaltar é que acho perigoso se a comunidade se separar e tivermos vários projetos diferentes e o garfo de um garfo. Não sou fã de fragmentação e acho melhor trabalharmos juntos do que um contra o outro. Claro que há outras pessoas que vão argumentar que a competição é ótima e que isso traria inovação também no projeto Three.js, mas eu acredito mais na colaboração 🙂

Acho que uma das maiores vantagens de three.js é sua acessibilidade. Os pontos que @ roomle-build listou piorariam a facilidade de uso do motor (especialmente no contexto de iniciantes). Eu voto para continuar usando JavaScript, a menos que uma linguagem de programação alternativa seja suportada nativamente nos navegadores.

Não sou fã de fragmentação e acho melhor trabalharmos juntos do que um contra o outro.

Ter mais mecanismos 3D na web não significa que os desenvolvedores trabalhem uns contra os outros. Às vezes, é realmente melhor se diferentes projetos se concentrarem em coisas diferentes.

Acho que uma das maiores vantagens de three.js é sua acessibilidade. Os pontos que @ roomle-build listou piorariam a facilidade de uso do motor (especialmente no contexto de iniciantes).

Não vejo dessa forma porque outros projetos criam seus códigos em TypeScript sem qualquer influência na acessibilidade. Eu mencionei Vue e Ember como exemplos antes. Talvez faça sentido revisar a postura contra o TypeScript? Não precisaríamos inventar algo, precisaríamos apenas copiar as abordagens bem-sucedidas de outros projetos. Além disso, acho que o TypeScript teria o benefício de three.js ser mais acessível para os contribuidores porque o IDE poderia ajudá-los a obter uma visão geral de todo o projeto mais rapidamente.

Eu voto para continuar usando JavaScript, a menos que uma linguagem de programação alternativa seja suportada nativamente nos navegadores.

Acho que isso não vai acontecer em um futuro próximo e, portanto, acho que devemos ter uma visão mais pragmática sobre o TypeScript. Como escrevi acima, acho que é apenas um problema de como o projeto e o repo são organizados e não uma compensação entre facilidade de uso e experiência de desenvolvimento.

Acho que deixamos nossa posição clara.

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

Questões relacionadas

jack-jun picture jack-jun  ·  3Comentários

Bandit picture Bandit  ·  3Comentários

filharvey picture filharvey  ·  3Comentários

jlaquinte picture jlaquinte  ·  3Comentários

Horray picture Horray  ·  3Comentários