Three.js: Arquivo "externo" do Google Closure Compiler para three.js?

Criado em 10 jul. 2011  ·  61Comentários  ·  Fonte: mrdoob/three.js

Oi

Existe algum arquivo externo para three.js? Eu quero dizer tal:

http://code.google.com/closure/compiler/docs/api-tutorial3.html#externs

Obrigado
Remo

Question

Comentários muito úteis

Hmmm, ainda não estou muito feliz com tantos comentários no código. Às vezes me pergunto se não seria melhor portar tudo para algo como TypeScript (uma pena que é propriedade da Microsoft).

Todos 61 comentários

Não, three.js não tem nenhuma dependência externa, então algo assim não era necessário até agora.

Eu sei, mas também é útil para projetos próprios integrar THREE.js em um ambiente compilável.

Como seria esse arquivo? Desculpe se já está explicado no link que você compartilhou, achei a página um pouco complicada (muito texto) e não consigo ler / entender.

@mrdoob , você encontra alguns de seus exemplos em:

http://code.google.com/p/closure-compiler/source/browse/#svn% 2Ftrunk% 2Fexterns

ou

http://code.google.com/p/closure-compiler/source/browse/#svn% 2Ftrunk% 2Fcontrib% 2Fexterns

e o seguinte também é importante:

http://code.google.com/closure/compiler/docs/js-for-compiler.html

Comentários / cabeçalhos? Acho que isso tornaria o código mais difícil de ler ...

Sim, mas acho que é apenas para esse arquivo externo, não para todo o código. Pode-se fazer isso, mas não é necessário.

Eu tentei com http://www.dotnetwise.com/Code/Externs/index.html . Mas não funciona completamente com Three.js. Nem todas as definições são extraídas.

Aqui está a entrada do blog:

http://blog.dotnetwise.com/2009/11/closure-compiler-externs-extractor.html

Parece que suporta o padrão this.method = function(){} , mas não os protótipos ...

@mrdoob , qual é sua recomendação para integrar THREE.js em um aplicativo próprio com o otimizador avançado do compilador de fechamento? É verdade que atualmente não é possível?

Pelo que entendi, o otimizador avançado inclui apenas as classes que estão sendo usadas, certo? Em teoria, deveria funcionar ... não está funcionando?

Não tentei a otimização avançada com three.js, mas me lembro de outras coisas que costumava quebrar o código. Em geral, não era "seguro" - com a otimização simples padrão sempre funciona, com o avançado às vezes não.

Ele quebra o código se você compilar é como uma biblioteca, mas como um aplicativo (com métodos sendo chamados e tudo mais) deve funcionar, certo?

@mrdoob para usar uma biblioteca com código compilado (otimizado), você precisa de um arquivo "externs" para declarar todas as classes e métodos da biblioteca. Não funciona sem ele. Mas existe outra ferramenta que funciona com three.js? Eu preciso ofuscar (uglify) meu aplicativo three.js. Um candidato é: https://github.com/mishoo/UglifyJS . Mas eu não tentei.

O fechamento externo do Google é um arquivo que descreve objetos inteiros que usaremos em nosso código compilado.
Sem este arquivo, o compilador apenas cria a partir de nomes de função algo como a () ou b ().

Por exemplo, isso é para JQuery: http://code.google.com/p/closure-compiler/source/browse/trunk/contrib/externs/jquery-1.7.js

Será ótimo se externos forem para three.js.

Estou bem com isso, mas não posso lidar com isso sozinho. Alguém terá de intensificar este assunto.

@yurikor , ao usar node.js, você pode usar node-browserify e uglify-js juntos. Então você não precisa construir nada.

@remoe Muito obrigado pelo conselho. Vou tentar.

Este problema está inativo há algum tempo, mas caso alguém queira resolvê-lo no futuro, aqui estão algumas informações adicionais:

Para meu projeto, criei um arquivo simples com exportações de threejs apenas o suficiente para poder compilar meu projeto. Ele vem com anotações de tipo que foram bastante úteis, pois permitiram que o compilador de encerramento verificasse todos os tipos e encontrasse alguns bugs no meu código. Eu criei este arquivo manualmente. Eu uso o compilador de encerramento principalmente para verificação de bugs, para a minificação real eu uso os uglifyjs menos poderosos, mas seguros.

Além disso, para evitar que o compilador de encerramento renomeie meus símbolos de interface pública, tive que adicionar várias linhas de código (essas quatro funções são as únicas funções públicas de minha biblioteca). Observe que o compilador de encerramento renomeia todas as propriedades acessadas por blah.xyz , mas não toca em nenhuma propriedade acessada por blah["xyz"] .

Finalmente, a linha window['ColladaLoader2'] = ColladaLoader2 (observe novamente o uso de uma string) foi necessária para informar ao compilador de encerramento que essa classe deveria ser exportada para o escopo global.

Mas você não está usando encerramento para produção e apenas verificação de bug? eu sou
não tenho certeza se vale a pena manter o arquivo externo. Apenas feche
sem otimizações agressivas e então você não precisa do arquivo externo
mas você ainda consegue a maior parte da validação que eu acredito ou talvez todas as
validação. Talvez você possa esclarecer?

Enviado do meu telefone, desculpe pela minha gramática e concisão.
Em 12 de fevereiro de 2013 5:19, "Robert Carnecky" [email protected] escreveu:

Este problema está inativo por um tempo, mas caso alguém queira
resolver esse problema no futuro, aqui estão algumas informações adicionais:

Para o meu projeto, criei um arquivo simpleshttps: //github.com/crobi/ColladaAnimationCompress/blob/master/threejs-exports.j com apenas três exportações suficientes para compilar meu projeto. Vêm
com anotações de tipo que foram bastante úteis, pois permitiram o fechamento
compilador para verificar todos os tipos e encontrar alguns bugs no meu código. eu tenho
criou este arquivo manualmente. Eu uso o compilador de encerramento principalmente para bug
verificando, para a minificação real eu uso o menos poderoso, mas seguro
uglifyjs https://github.com/mishoo/UglifyJS.

Além disso, para evitar que o compilador de encerramento renomeie minha interface pública
símbolos, tive que adicionar várias linhas de codehttps: //github.com/crobi/ColladaAnimationCompress/blob/366344d3aa5dbbc0a53c47a2c1759b86bb1e0fcd/ColladaLoader2.coffee#L3376 (essas quatro funções são as únicas funções públicas de minha biblioteca). Observação
que o compilador de encerramento renomeie todas as propriedades acessadas via blah.xyz,
mas não toca em nenhuma propriedade acessada via blah ["xyz"].

Por fim, a linhahttps: //github.com/crobi/ColladaAnimationCompress/blob/366344d3aa5dbbc0a53c47a2c1759b86bb1e0fcd/ColladaLoader2.coffee#L3383 window ['ColladaLoader2']
= ColladaLoader2 (observe novamente o uso de uma string) foi necessário para informar o
compilador de fechamento que esta classe deve ser exportada para o escopo global.

-
Responda a este e-mail diretamente ou visualize-o em Gi tHubhttps: //github.com/mrdoob/three.js/issues/341#issuecomment -13426131.

Pelo que eu sei, o modo simples não faz nenhuma validação. Ele renomeia as variáveis ​​locais e, se encontrar um símbolo desconhecido, não o altera, assumindo que seja uma variável global.

O modo avançado se comporta como um compilador em uma linguagem fortemente tipada (assumindo que informações de tipo estejam disponíveis): ele avisa sobre funções ou propriedades desconhecidas, avisa se você chamou uma função com o número errado de argumentos ou se você usou um parâmetro de string onde um número era esperado.

Por exemplo, o modo simples transforma o seguinte código

function fn() {
    var foo = {}; // local variable, safe to rename this
    foo.bar();    // undefined property, will crash here
}
fn();

sem quaisquer avisos para

function fn(){({}).bar()}fn();

que obviamente irá travar em ({}).bar() . O modo avançado gera o seguinte código

({}).a(); // fn() inlined, private member 'bar' renamed to 'a'

que ainda trava, mas o compilador também dá um aviso

Property bar never defined on foo at line 3 character 0.
  • O fechamento de bugs encontrado foi o tipo de bug em que eu cometi um erro de digitação no nome de uma função ou em que passei um THREE.Vector3 para Matrix4.makeTranslation vez de três números separados para os componentes x, y e z .
  • Se eu tivesse uma cobertura de teste completa (o que não tenho), teria encontrado esses bugs mais cedo ou mais tarde. Às vezes, eles são difíceis de depurar, no entanto, se não se manifestarem imediatamente.
  • Se threejs fornecesse um arquivo de exportação atualizado com cada nova versão (grande esforço para manter), o compilador de encerramento pegaria todos os problemas provenientes de uma API em mudança (como era o caso de Matrix4.makeTranslation ).
  • Configurar o compilador de encerramento é muito trabalhoso para mim, pois ele precisa de um tempo de execução Java. Todas as outras ferramentas necessárias para construir minha biblioteca são baseadas em node / javascript.

No momento, estou construindo meu arquivo externs.js da biblioteca de encerramento para integrar um aplicativo THREE.js com a Biblioteca do Closure. Basicamente, o que estamos tentando descobrir é:
Existe uma lista em algum lugar de todas as classes THREE.js e os métodos de protótipo que implementam? A lista deve ser mais ou menos assim:

TRÊS.Textura
THREE.Texture.constructor
THREE.Texture.clone
THREE.Texture.dispose
THREE.DataTexture.clone

(e assim por diante...)

Ps- Three.js é ótimo, mas com jsDocs adequado, essa lista pode ser facilmente extraída :)

Eu tenho uma implementação parcial de exportações de three.js aqui (escrita manualmente, então pode conter alguns erros).

@crobi : por que você colocou os comentários do documento nele? Parece que consumiu muito tempo e não tenho certeza se é necessário ...

@taoeffect : os comentários são principalmente para o modo avançado do compilador de encerramento. Eu gosto de código fortemente tipado.

@crobi , oh, os comentários resultam em digitação forçada? Isso é legal, eu não sabia disso.

Somente se você usar o compilador de encerramento para verificar erros de tipo. Semelhante ao texto datilografado . Ambos pré-processam o javascript anotado em javascript simples. Portanto, é apenas uma verificação de tempo de compilação.

A maioria dos comentários sobre o modo de otimizações avançadas de fechamento aqui são imprecisos.

Para resolver o problema principal, você pode usar a ferramenta a seguir para gerar automaticamente os externos de fechamento para qualquer biblioteca http://www.dotnetwise.com/Code/Externs/

Além disso, se você decidir usar three.js como entrada para seu código em vez de simplesmente usá-lo como uma biblioteca externa, você precisará adicionar o sinalizador

--language_in=ECMASCRIPT5

Você deveria escrever uma postagem no blog sobre isso, talvez tendo uma performance
exemplo crítico e ver se executá-lo através do Google Closure
compilador com boas otimizações faz a diferença.
-ben

Na segunda-feira, 13 de janeiro de 2014 às 12h31, Rodrigo Formigone <
notificaçõ[email protected]> escreveu:

Além disso, se você decidir usar three.js como entrada para seu código, em vez de
simplesmente usando-o como uma biblioteca externa, você precisará adicionar o sinalizador

--language_in = ECMASCRIPT5

-
Responda a este e-mail diretamente ou visualize-o em Gi tHubhttps: //github.com/mrdoob/three.js/issues/341#issuecomment -32191167
.

Atenciosamente,
Ben Houston
Voz: 613-762-4113 Skype: ben.exocortex Twitter: @exocortexcom
http://Clara.io - Criação de conteúdo 3D baseado em WebGL de nível profissional

Acho que devo escrever um post assim. Porém, apenas para esclarecer, o motivo pelo qual alguém deseja executar o Three.js por meio do encerramento (com ou sem um arquivo externo) não é necessariamente apenas para as otimizações de desempenho. Closure tem como objetivo principal ajudá-lo a escrever código sustentável em JavaScript (particularmente, bases de código muito grandes). O objetivo é ajudar os desenvolvedores a "domar" o JavaScript (escrevendo JS nativo), em vez de "evitá-lo" (usando GWT ou outras ferramentas semelhantes). Se você simplesmente tentar compilar Three.js como parte de um projeto Closure, o compilador pode gritar com você porque Three.js pode não estar em conformidade com alguns de seus padrões (não é JSDoc o suficiente, talvez?). Usar o sinalizador do compilador --language_in resolve isso a partir de agora, embora você receba alguns avisos. Se você simplesmente deseja compilar seu próprio código JS, mas faz referência a Three.js como uma biblioteca externa (deixando assim toda a base de código de Three.js intocada e não otimizada), você precisará do arquivo externo mencionado acima. Sem o arquivo externo, o Closure lançará erros de compilação dizendo que THREE. * Não está declarado em lugar nenhum, etc.

Embora eu não comece a escrever minha postagem do blog explicando como e por que alguém pode querer usar Three.js em um projeto de Closure, aqui está a melhor apresentação introdutória sobre as ferramentas do Google Closure que já vi: (do Google I / O 2011) https://www.youtube.com/watch?v=M3uWx-fhjUc (Eu sei que é um vídeo longo, mas realmente deixa claro qual é o propósito do compilador e o que os diferentes modos de compilação realmente fazem. Também descreve porque você precisa de um arquivo externo).

Olá, estou ansioso para desenvolver um aplicativo usando three.js e, portanto, desejo o suporte para a opção ADVANCED_OPTIMIZATIONS.

A remoção de código morto funciona fortemente quando o aplicativo de incorporação usa apenas uma parte das funções do Three.js.

Atualmente, three.js requer cada função desenvolvida, porque o uso pretendido está confinado a "Apenas exigir três.min.js!". Esta abordagem clássica é fácil de entender, mas para códigos escritos por esta abordagem, minimizadores de JavaScript podem reduzir o código tamanho apenas diminuindo os nomes de variáveis ​​(não é eficaz para nomes de variáveis ​​curtos), removendo espaços (apenas eficaz para espaços de indentação, tabulações e quebras de linha) e outros truques baratos.

Ao usar a opção ADVANCED_OPTIMIZATIONS para um código com "estilo de compilador Closure", ele pode remover todos os "códigos desnecessários", que pesam principalmente grandes bibliotecas. Bibliotecas como a biblioteca Closure tornaram-se grandes, mas os usuários e desenvolvedores de bibliotecas não se importam com isso porque sabem que a maior parte do código será removida no estágio de compilação.

Como three.js já foi escrito no estilo orientado a objetos, acho que não é (tecnicamente) difícil atualizar o código inteiro para o código "com estilo de compilador Closure". As coisas com que me preocupo ...

  • O estilo do compilador de fechamento requer anotações para cada função. Currenly, não há nenhum deles. Quanto tempo levará para adicionar anotações a todas as funções já desenvolvidas?
  • O compilador de fechamento requer definições de tipo estritas. Mesmo para nulos e indefinidos, você deve trabalhar para eles corretamente. Pode ser um trabalho árduo para funções que têm parâmetros "permitidos para nulos", parâmetros "permitidos indefinidos", ...
  • Você deve preparar um arquivo externo adequado, se estiver ansioso para preparar a "biblioteca com versão completa" compilada por ADVANCED_OPTIMIZATIONS.

Hai Schedul Xor,

Esta é uma boa ideia. Você poderia compartilhar um pequeno trecho sobre como
isso tem que ser adicionado ao three.js?

Atenciosamente,

Ramsundhar Madhavan

Na terça-feira, 24 de junho de 2014 às 16h23, Schedul Xor [email protected]
escreveu:

Olá, estou ansioso para desenvolver um aplicativo usando three.js e
portanto, desejando suporte para a opção ADVANCED_OPTIMIZATIONS.

A remoção de código morto funciona fortemente quando o aplicativo de incorporação usa apenas
uma parte das funções de Three.js.

Atualmente, three.js requer todas as funções desenvolvidas, porque o
o uso pretendido é confinado a "Exigir apenas três.min.js!". Este clássico
abordagem é fácil de entender, mas para códigos escritos por esta abordagem,
Minimizadores de JavaScript podem reduzir o tamanho do código apenas diminuindo os nomes de variáveis
(não é eficaz para nomes de variáveis ​​curtas), removendo espaços (apenas eficaz
para espaços de recuo, tabulações e quebras de linha) e outros truques baratos.

Usando a opção ADVANCED_OPTIMIZATIONS para um "Compilador de fechamento estilizado"
código, ele pode remover todos os "códigos não necessários", que pesam principalmente
grandes bibliotecas. Bibliotecas como a biblioteca Closure
https://developers.google.com/closure/library/ tornou-se grande, mas
usuários de bibliotecas e desenvolvedores não se importam com isso porque sabem que
a maior parte do código será removida no estágio de compilação.

Uma vez que three.js já está escrito no estilo orientado a objetos, eu acho que é
não (tecnicamente) difícil atualizar todo o código para "Compilador de fechamento
com estilo ". As coisas com que me preocupo ...

  • O estilo do compilador de fechamento requer anotações para cada função.
    Currenly, não há nenhum deles. Quanto tempo leva para adicionar anotações
    para todas as funções já desenvolvidas?
  • O compilador de fechamento requer definições de tipo estritas. Mesmo para nulo e
    indefinido, você deve trabalhar para eles adequadamente. Pode ser um trabalho árduo para
    funções que têm parâmetros "permitidos para nulos", "permitidos para indefinidos"
    parâmetros, ...
  • Você deve preparar um arquivo externo adequado, se estiver ansioso
    para preparar a "biblioteca com versão completa" compilada por
    ADVANCED_OPTIMIZATIONS.

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/mrdoob/three.js/issues/341#issuecomment -46957189.

@ schedul-xor definitivamente precisamos de ajuda com isso ... as anotações de código são realmente necessárias ou é suficiente com externos?

Oi,

Eu sou novo nesta comunidade, estou interessado em contribuir com estes
alterar.

Atenciosamente,

Ramsundhar Madhavan

Na terça-feira, 24 de junho de 2014 às 19h23, Mr.doob [email protected] escreveu:

@ schedul-xor https://github.com/schedul-xor , definitivamente precisamos de ajuda
com isso ... as anotações de código são realmente necessárias ou basta com
externos?

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/mrdoob/three.js/issues/341#issuecomment -46973166.

Lembre-se de que as otimizações avançadas exigem um certo estilo de codificação ou irão corromper seu código. Por exemplo, three.js mistura uniforms["diffuse"] e uniforms.diffuse , o que não é permitido em otimizações avançadas de fechamento. Veja também # 3222.

Adicionar anotações de tipo estrito em todos os lugares é uma grande quantidade de trabalho e adiciona muitas linhas de comentário (no meu projeto, aumentou a contagem de linha por um fator de 2).

Ter arquivos externos para outros frameworks / linguagens da web é bom.

De acordo com o tutorial , os externos são usados ​​para proteger as variáveis ​​que você não deseja que sejam renomeadas. Isso é o que você usa quando deseja proteger bibliotecas de terceiros (sem estilo de compilador de encerramento), usando em seu projeto com estilo de compilador de encerramento, de renomeações agressivas de variáveis.

Não tenho certeza se o compilador ainda tentará cortar o código morto, mesmo quando o arquivo externo é a única coisa fornecida. Será muito mais fácil se você escrever apenas arquivos externos, em vez de escrever anotações para todas as funções ...

Mesmo assim, na minha opinião, escrever anotações para cada função é melhor do que escrever externos, porque ficará difícil sincronizar o arquivo externo posteriormente, se o arquivo de definição de tipo e o código-fonte forem diferentes. Você pode imaginar como seria irritante se cada correção de função exigir uma atualização de arquivo externo. Qualquer uma das opções (externa ou / ** * / comentário nas funções) requer anotação, na maioria dos casos o método mais fácil vence.

Como three.js é um projeto grande, estou me perguntando onde devo trabalhar pela primeira vez. Será melhor começar pelo que pode ser feito facilmente.

Que tal colocar cabeçalhos de arquivo, alterar o estilo de definição de função para cada função?

THREE.Material = function(){
  :
};
THREE.Material.prototype = {
    constructor: THREE.Material,
    setValues: function ( values1, value2 ) {}
    getValues: function () { return this.a; }
    :
};

goog.provide('THREE.Material'); ← Write goog.provide('package.classname') at the first line

← three empty lines before <strong i="10">@constructor</strong>

/**
 * <strong i="11">@constructor</strong> ← Add <strong i="12">@constructor</strong> annotation to constructor
 */
THREE.Material = function(){
  :
};

← two empty lines before function definition
/**
 * <strong i="13">@param</strong> {!Array.<!string>} values1 Values1 explanation ← values1 is an array of strings. values1 can't be null, and elements inside values1 can't be null.
 * <strong i="14">@param</strong> {!number} value2 Value2 explanation ← value2 is a number.
 */
THREE.Material.prototype.setValue = function(values1, value2){
  goog.asserts.assertArray(values1);
  goog.asserts.assertNumber(value2);
  :
};


/**
 * <strong i="15">@return</strong> {!number} ← This function returns a non-null number.
 */
THREE.Material.prototype.getValue = function(){
  return this.a;
};

Será mais fácil restringir todos os tipos de parâmetro e retornar tipos de valor como não nulos. Isso tornará muito mais fácil passar erros de compilação ADVANCED_OPTIMIZATIONS.

Hmmm, ainda não estou muito feliz com tantos comentários no código. Às vezes me pergunto se não seria melhor portar tudo para algo como TypeScript (uma pena que é propriedade da Microsoft).

Texto datilografado parece muito mais agradável para javascript fortemente tipado do que closure. Esta é minha experiência depois de ter reescrito um carregador de collada de tamanho moderado primeiro para javascript compatível com closure e depois para typescript. Ambas as abordagens ajudaram a encontrar bugs em tempo de compilação. O closure realizou algumas otimizações muito boas (inlining, remoção de código morto) do meu código e tem suporte para tipos anuláveis. Por outro lado, a grande quantidade de comentários distraía e o suporte IDE (para conclusão de código) não era tão bom quanto com o texto digitado. Além disso, escrever classes em texto datilografado é muito mais fácil devido à palavra-chave semelhante a ECMAScript6 class .

Mas isso é apenas uma opinião pessoal. Mais importante, quero enfatizar novamente o fato de que você deve garantir que todos os acessos de propriedade sejam consistentes antes de oferecer suporte oficial ao encerramento no modo de compilação avançada. Ter um arquivo externo não ajuda, o acesso à propriedade deve ser consistente para objetos internos que não são exportados, uma vez que você _quer_ que eles sejam renomeados / embutidos / removidos agressivamente. Você detectará acessos de propriedade inconsistentes se anotar cada classe e cada variável, mas fazer isso para a base de código three.js inteira leva várias semanas (se eu extrapolar quanto tempo levou para anotar meu projeto).

Finalmente, portar um projeto tão grande como three.js para qualquer outra linguagem / estrutura / estilo de codificação é algo que deve ser discutido em detalhes.

OK, concordo que three.js é enorme e, portanto, adicionar anotações a cada função pode levar várias semanas. Pode haver AltJSs melhores do que o fechamento. Isso deve ser discutido (se você estiver ansioso para portá-lo para outra coisa) mais profundamente.

Desculpe, mal posso esperar. Vou fazer um fork do commit atual e começar a portar.

Oi,

É possível automatizar a adição dessas anotações? Em caso afirmativo, podemos adicioná-lo
para build.py e adicionar antes de habilitarmos a otimização avançada de fechamento.

Atenciosamente,

Ramsundhar Madhavan

Na quarta-feira, 25 de junho de 2014 às 6h05, Schedul Xor [email protected]
escreveu:

OK, concordo que three.js é enorme e, portanto, adicionar anotações a cada
funções podem levar várias semanas. Pode haver AltJSs melhores do que
fecho. Isso deve ser discutido (se você estiver ansioso para transferi-lo para
outra coisa) mais profundamente.

Desculpe, mal posso esperar. Vou fazer um fork do commit atual e começar a portar.

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/mrdoob/three.js/issues/341#issuecomment -47047966.

@ ramsundhar20 , na minha opinião, adicionar anotações (imprecisas? melhor do que nada. não é um grande problema. pode ser atualizado) primeiro tornará a automação muito mais fácil.

Three.js atualmente contém 163 arquivos javascript com 1354 funções definidas. Sim, é enorme, mas não é um objetivo muito distante.

// Estou com medo se este tópico estiver fora do lugar ...

@ schedul-xor novamente, não sou muito fã de ter um comentário por função: /

@mrdoob OK, eu entendi.

Respeitando sua política, gostaria de adicionar comentários por função apenas no meu fork. Além disso, nunca farei solicitações de pull. Em vez disso, vou portar as modificações originais do three.js para meu fork com estilo de closure. Sua consideração favorável seria apreciada.

Isso soa bem :)

Obrigado! Vou começar a trabalhar nisso.

Existe pelo menos um arquivo externo three.js de base para ser usado com o compilador de encerramento? Isso não exige que o código-fonte do Three.js tenha quaisquer anotações adicionais do estilo do Google, isso é apenas para tornar a vinculação de um app.js externo que usa three.js compilável / ofuscado o suficiente?

Também estou muito interessado em um arquivo externs completo e de qualidade para three.js. Aqui está um, mas não está completo:

https://github.com/cljsjs/packages/blob/master/three/resources/cljsjs/three/common/three.ext.js

Suponho que uma maneira de fazer isso é começar com este e adicionar manualmente as coisas que você usa.

Sim, conte meu voto. Idealmente para um modo avançado compilável, threejs 100% digitados - ou um arquivo externo, no mínimo.

A inferência de tipos ficou melhor e a desordem necessária diminuiu. Com escopos e aliases em vigor, o código não precisa ser tão detalhado quanto a biblioteca de encerramento. Basicamente, tudo se resume a escrever documentos inline digitados no caso de código limpo. Eles são realmente ruins o suficiente para compensar todos os benefícios?

Configurações superagressivas, isto é, modo avançado + compactação JS + otimizações baseadas em tipo, não apenas removerão o código morto, mas podem fazer todas as coisas legais que um compilador de otimização pode fazer:

Constantes / enums nomeados serão substituídos por numerais. Além disso, o compilador pode rastrear constância, realizar cálculos com outras constantes e, finalmente, inserir um número simples onde for necessário. O controle de fluxo dependente fica sujeito à eliminação de código morto, é claro. As funções que têm apenas um site de chamada ativo no aplicativo resultante e aquelas cujo formato compactado terminará menor do que sua definição salvaria ficam embutidas. Os namespaces são removidos. Todos os nomes desprotegidos são reduzidos ao mínimo.

Lookup é comparativamente caro em JavaScript. A combinação de renomeação, dobramento constante e inlining removerá muitas pesquisas e inúmeras chamadas de função. Além disso, dado um cabeçalho apropriado (existe um na biblioteca de encerramento), todas as constantes WebGL padronizadas podem ser incluídas no renderizador.

O resultado é uma biblioteca menor, mais rápida, autodocumentável e automaticamente personalizável. O compilador também detectará muitos mais bugs em configurações mais agressivas - provavelmente facilitará a revisão do código. Por último, mas não menos importante, há o efeito de ofuscação: agrupar o código do cliente com a biblioteca personalizada fornece uma proteção muito melhor contra roubo de propriedade intelectual do que o código com símbolos reveladores que foram preservados por meio de um arquivo externo.

Não consigo encontrar o branch mencionado acima. Alguém ainda está trabalhando em uma versão digitada?

@mrdoob Alguma esperança de uma mudança de

Eu ficaria feliz em ajudar.

@mrdoob Alguma esperança de uma mudança de

No momento, estou focando na refatoração de WebGLRenderer 😇

Pode alterar as constantes para const vez de var tem um bom suporte para todos os navegadores WebGL https://kangax.github.io/compat-table/es6/ (const-> basic) e js os motores estão começando a otimizar para const Acelerando constantes globais usando a otimização de campo fixo

Interessante, porém, já que só funciona no lugar de var , aplicável apenas a uma fração muito pequena dos casos de que estou falando - mesmo quando seriam apenas sobre constantes. Além disso, os compiladores JIT estão com pressa por definição, portanto, naturalmente, não podem competir com otimizações de programas inteiros realizadas por uma ferramenta offline. Cada mecanismo JS deve respeitar a estrutura do código e não pode refatorá-lo arbitrariamente, pois esperamos ser capazes de, por exemplo, abrir o console e encontrar o programa que colocamos nele, substituir uma função específica, etc.

De volta ao suporte ao compilador de encerramento: Fiz algumas leituras e experimentos. Aqui está o que descobri:

  • Nenhuma anotação é necessária para executar o modo avançado,
  • anotações podem ser adicionadas gradualmente para aumentar o nível de otimização, e
  • o carregador precisa de alguns cuidados para continuar funcionando, mas é bastante fácil.

Existem basicamente três casos de uso diferentes:

  1. Os modelos podem ser compactados juntamente com o aplicativo e a biblioteca.
  2. O aplicativo e a biblioteca são compactados. Os modelos são carregados em tempo de execução.
  3. A biblioteca é compilada no modo básico e um aplicativo de modo avançado deseja usá-la.

O terceiro requer um arquivo externo para todos os Three.js e é muito trabalhoso para poucos benefícios da IMO. Portanto, discutirei apenas os dois primeiros - estes são os preferidos, de qualquer maneira:

Quando o compilador vê

anObject['aProperty']

ele não tocará no nome da propriedade (nenhuma string é alterada).

anObject.aProperty

por outro lado, permite que o compilador renomeie a propriedade de forma consistente, a menos que saiba que anObject é externo ao aplicativo que está sendo compilado. O compilador sabe disso a partir de _externs_ internos ou fornecidos explicitamente.

Aí vem a receita:

  • Fazemos com que o carregador acesse consistentemente as propriedades usando a notação de ponto.
  • Nós digitamos a entrada e gravamos um arquivo externo apenas para o JSON .
  • Compilar com esse arquivo externo deve ser tudo o que você precisa para fazer o caso de uso 2 funcionar.
  • Para o caso de uso 1, não usamos o arquivo externo, mas, em vez disso, retiramos as aspas das chaves do objeto no JSON:
{
    "camera": {
        "object": {
    // ...

simplesmente se tornaria

{
    camera: {
        object: {
    // ...

Muito simples, não é?

O caso de uso 1 se torna ainda mais atraente quando o formato JSON permitiria dados binários externos (brutos ou compactados via webgl-loader ou o3dgc) - tecnicamente, outro recurso completamente ortogonal ao suporte de fechamento, é claro.

O arquivo externo também pode substituir páginas Wiki sempre desatualizadas que documentam o formato do arquivo :-).

Eu sei que este problema foi resolvido há algum tempo. No entanto, recentemente tive o mesmo problema ao usar three.js em um projeto de compilador de encerramento e fui parar nesta página. Eu escrevi uma ferramenta que transforma .d.ts (arquivos de declaração de texto digitado) em um arquivo de compilador de encerramento. Usando a ferramenta e o ótimo arquivo descritor DefinitelyTyped / threejs descrito, funciona perfeitamente.
A ferramenta: https://github.com/eredo/tsd2cce ou instale via npm install -g tsd2cce

Espero que isto ajude...

@eredo que me ajudou totalmente. Todos os outros geradores que experimentei não tinham um bom número de definições de método para a biblioteca three.js. Obrigado!

@eredo @Corkle ou qualquer outra pessoa, você pode nos mostrar como usar tsd2cce ? O primeiro arg é claramente o arquivo de definição .d.ts, mas qual é o segundo arg? Estou pegando esse problema. https://github.com/eredo/tsd2cce/issues/6

Na verdade, descobri que usar o r73 d.ts de fevereiro funciona bem com o tsd2cce, mas o r73 é muito antigo para mim.

A maneira correta de fazer isso agora seria usar tsickle para gerar arquivos d.ts.

Olá a todos,

Para a posteridade e para o benefício de todos, decidi relatar aqui minhas próprias tentativas de reduzir ainda mais a biblioteca com ADVANCED_OPTIMIZATIONS do Google Closure Compiler e alguns outros ajustes.

Eu criei um extern.js que permite Three.min.js com otimizações avançadas ativadas. É muito longe de ser perfeito.

Para criá-lo, comecei com um extern.js com base em exemplos anteriores neste tópico. A biblioteca foi quebrada quando compilada desta forma por causa de propriedades mutiladas não incluídas naquele arquivo externo. Usando a opção --property_renaming_report no compilador de encerramento, obtive a lista completa de propriedades mutiladas. Depois de adicionar TODAS essas propriedades ao extern.js, as propriedades não foram mais mutiladas e a saída foi a mesma que SIMPLE_OPTIMIZATIONS. A partir daí, comecei a comentar seletivamente / manualmente as seções do extern.js e confirmei que a biblioteca ainda funcionava de forma reduzida.

Eu ADORARIA automatizar essa suposição e verificação e obter um extern.js perfeito que destrói com segurança o maior número possível de nomes de propriedades. Tive a ideia de usar os testes de unidade para THREE.JS e determinar programaticamente quais nomes de propriedade mutilados resultavam em testes com falha, mas não parece possível executar os testes de unidade na linha de comando atualmente, por exemplo, com phantomjs. (Provavelmente devido ao WebGL)?

De qualquer forma, isso é um "progresso" em direção a uma biblioteca reduzida menor, me ajudando a manter o tamanho geral do javascript do meu SPA baixo.

externs.js

comando package.json build-closure atualizado

Eu também usei comandos string replace para remover todas as mensagens console.warn e console.error da biblioteca, como você pode ver no comando build-closure. Com isso, e comentando certas seções do código, reduzi a lib minimizada em cerca de 20% até agora e há espaço para melhorias.

@mrdoob Fazendo algo como meu método aqui, você poderia eventualmente fornecer um extern.js que permite ADVANCED_OPTIMIZATIONS sem bagunçar o código com anotações específicas para aquele compilador, o que parecia ser sua principal preocupação.

@ medmr1 Incrível! Você já tentou compilar seu aplicativo com a biblioteca three.js em um? Isso evitaria a necessidade de um arquivo externo idealmente.

Não tentei construir tudo dentro de um fechamento, não. Isso pode funcionar bem, mas suspeito que ainda haverá problemas com relação à mutilação de algumas propriedades referidas de forma programática. Coisas do IE, como var thing = ShaderLib[ shaderType + "BumpMapFrag"] Mas talvez eu me poupe de muitos problemas?

Sim, algo como var thing = ShaderLib[ shaderType + "BumpMapFrag"] será interrompido com otimizações avançadas. as referências de propriedade precisam ser estaticamente analisáveis. Você poderia fazer algo como:

function(shaderType) {
  if (shaderType == "a") {
    return ShaderLib.aBumpMapFrag;
  }
  if (shaderType == "b") {
    return ShaderLib.bBumpMapFrag;
  }
...

Construir um arquivo externo correto é definitivamente mais benéfico para o projeto como um todo, pois a maioria das pessoas não compilará seu aplicativo com o Closure Compiler, apenas usará a versão reduzida publicada.

Em vez de externos, você também pode experimentar a anotação @export .
https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#export -export-Someype

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