Three.js: Fichier "externs" du compilateur de fermeture Google pour three.js ?

Créé le 10 juil. 2011  ·  61Commentaires  ·  Source: mrdoob/three.js

salut

Existe-t-il un fichier externe pour three.js ? Je veux dire un tel :

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

Merci
Remo

Question

Commentaire le plus utile

Hmmm, je ne suis toujours pas très content d'avoir des tonnes de commentaires dans le code. Parfois, je me demande s'il ne serait pas préférable de porter le tout sur quelque chose comme TypeScript à la place (dommage que celui-ci appartienne à Microsoft).

Tous les 61 commentaires

Non, three.js n'a pas de dépendances externes, donc quelque chose comme ça n'était pas nécessaire jusqu'à présent.

Je sais, mais il est également utile pour ses propres projets d'intégrer THREE.js dans un environnement compilable.

A quoi ressemblerait un tel fichier ? Désolé si c'est déjà expliqué sur le lien que vous avez partagé, j'ai trouvé la page un peu accablante (trop de texte) et je n'arrive pas à lire/comprendre.

@mrdoob , vous trouverez certains de leurs exemples sur :

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

et ce qui suit est également important :

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

Commentaires/En-têtes ? Je pense que cela rendrait le code plus difficile à lire...

Oui, mais je pense que ce n'est que pour ce fichier externe, pas pour l'ensemble du code. On peut le faire, mais ce n'est pas nécessaire.

Je l'ai essayé avec http://www.dotnetwise.com/Code/Externs/index.html . Mais cela ne fonctionne pas complètement avec Three.js . Toutes les définitions ne sont pas extraites.

Voici l'entrée du blog :

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

On dirait qu'il prend en charge le modèle this.method = function(){} , mais pas les prototypes...

@mrdoob , quelle est votre recommandation pour intégrer THREE.js dans une propre application avec l'optimiseur avancé du compilateur de fermeture ? Est-ce vrai que ce n'est pas possible actuellement ?

Pour autant que je sache, l'optimiseur avancé n'inclut que les classes utilisées, n'est-ce pas ? En théorie ça devrait marcher... ça ne marche pas ?

Je n'ai pas essayé l'optimisation avancée avec three.js, mais je me souviens pour d'autres choses qu'il cassait le code. En général, ce n'était pas "sûr" - avec l'optimisation simple par défaut, cela fonctionne toujours, avec les versions avancées, parfois non.

Cela casse le code si vous compilez en tant que bibliothèque, mais en tant qu'application (avec des méthodes appelées et tout cela), cela devrait fonctionner, n'est-ce pas ?

@mrdoob pour utiliser une bibliothèque avec du code compilé (optimisé), vous avez besoin d'un fichier "externs" pour déclarer toutes les classes et méthodes de la bibliothèque. Ça ne marche pas sans. Mais existe-t-il un autre outil qui fonctionne avec three.js ? J'en ai besoin pour obscurcir (uglifier) ​​mon application three.js. Un candidat est : https://github.com/mishoo/UglifyJS . Mais je ne l'ai pas essayé.

Externs de fermeture de Google est un fichier, qui décrit des objets entiers, que nous utiliserons dans notre code compilé.
Sans ce fichier, le compilateur crée simplement à partir des noms de fonction quelque chose comme a() ou b().

Par exemple, c'est pour JQuery : http://code.google.com/p/closure-compiler/source/browse/trunk/contrib/externs/jquery-1.7.js

Ce serait génial si les externes étaient pour three.js.

Je suis cool avec ça, mais je ne peux pas m'en occuper moi-même. Quelqu'un d'autre devra intervenir sur celui-ci.

@yurikor , lorsque vous utilisez node.js, vous pouvez utiliser node-browserify et uglify-js ensemble. Ensuite, vous n'avez pas besoin de construire quoi que ce soit.

@remoe Merci beaucoup pour les conseils. Je vais l'essayer.

Ce problème est inactif depuis un certain temps, mais au cas où quelqu'un voudrait s'attaquer à ce problème à l'avenir, voici quelques informations supplémentaires :

Pour mon projet, j'ai créé un fichier simple avec juste assez d'exports threejs pour pouvoir compiler mon projet. Il est livré avec des annotations de type qui étaient très utiles car elles permettaient au compilateur de fermeture de vérifier tous les types et de trouver quelques bogues dans mon code. J'ai créé ce fichier manuellement. J'utilise le compilateur de fermeture principalement pour la vérification des bogues, pour la minification réelle, j'utilise uglifyjs , moins puissant mais sûr.

De plus, pour empêcher le compilateur de fermeture de renommer mes symboles d'interface publique, j'ai dû ajouter plusieurs lignes de code (ces quatre fonctions sont les seules fonctions publiques de ma bibliothèque). Notez que le compilateur de fermeture renomme toutes les propriétés accessibles via blah.xyz , mais ne touche aucune propriété accessible via blah["xyz"] .

Enfin, la ligne window['ColladaLoader2'] = ColladaLoader2 (notez encore l'utilisation d'une chaîne) était nécessaire pour indiquer au compilateur de fermeture que cette classe devait être exportée vers la portée globale.

Mais vous n'utilisez pas la fermeture pour la production et vous vous contentez de vérifier les bogues ? Je suis
Je ne sais pas si la maintenance du fichier externe en vaut la peine. Exécutez simplement la fermeture
sans optimisations agressives et vous n'avez pas besoin du fichier externe
mais vous obtenez toujours la plupart de la validation je crois ou peut-être tous les
validation. Peut-être pouvez-vous clarifier?

Envoyé depuis mon téléphone, désolé pour ma grammaire et ma concision.
Le 12 février 2013 à 05h19, "Robert Carnecky" [email protected] a écrit :

Ce problème est inactif depuis un certain temps, mais au cas où quelqu'un voudrait
résoudre ce problème à l'avenir, voici quelques informations supplémentaires :

Pour mon projet, j'ai créé un simple fichierhttps://github.com/crobi/ColladaAnimationCompress/blob/master/threejs-exports.js avec juste assez d'exports threejs pour pouvoir compiler mon projet. Ça arrive
avec des annotations de type ce qui était très utile car il permettait la fermeture
compilateur pour vérifier tous les types et trouver quelques bogues dans mon code. j'ai
créé ce fichier manuellement. J'utilise le compilateur de fermeture principalement pour les bogues
vérification, pour la minification réelle, j'utilise le moins puissant mais sûr
uglifyjs https://github.com/mishoo/UglifyJS.

Aussi, pour empêcher le compilateur de fermeture de renommer mon interface publique
symboles, j'ai dû ajouter plusieurs lignes de codehttps://github.com/crobi/ColladaAnimationCompress/blob/366344d3aa5dbbc0a53c47a2c1759b86bb1e0fcd/ColladaLoader2.coffee#L3376 (ces quatre fonctions sont les seules fonctions publiques de ma bibliothèque). Noter
que le compilateur de fermeture renomme toutes les propriétés accessibles via blah.xyz,
mais ne touche aucune propriété accessible via blah["xyz"].

Enfin, la lignehttps://github.com/crobi/ColladaAnimationCompress/blob/366344d3aa5dbbc0a53c47a2c1759b86bb1e0fcd/ColladaLoader2.coffee#L3383 window['ColladaLoader2']
= ColladaLoader2 (notez encore l'utilisation d'une chaîne) était nécessaire pour indiquer au
compilateur de fermeture que cette classe doit être exportée vers la portée globale.

-
Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps://github.com/mrdoob/three.js/issues/341#issuecomment -13426131.

Pour autant que je sache, le mode simple ne fait aucune validation. Il renomme les variables locales, et s'il rencontre un symbole inconnu, il le laisse intact, en supposant qu'il s'agit d'une variable globale.

Le mode avancé se comporte comme un compilateur dans un langage fortement typé (en supposant que les informations de type soient disponibles) : il avertit des fonctions ou propriétés inconnues, avertit si vous avez appelé une fonction avec le mauvais nombre d'arguments ou si vous avez utilisé un paramètre de chaîne où un nombre était attendu.

A titre d'exemple, le mode simple transforme le code suivant

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

sans aucun avertissement dans

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

qui va évidemment planter sur ({}).bar() . Le mode avancé génère le code suivant

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

qui plante toujours, mais le compilateur donne également un avertissement

Property bar never defined on foo at line 3 character 0.
  • La fermeture de bogues trouvée était le type de bogues où j'avais une faute de frappe dans un nom de fonction ou où j'ai passé un THREE.Vector3 à Matrix4.makeTranslation au lieu de trois nombres séparés pour les composants x, y et z .
  • Si j'avais une couverture complète des tests (ce que je n'ai pas), j'aurais trouvé ces bogues tôt ou tard. Parfois, ils sont difficiles à déboguer s'ils ne se manifestent pas immédiatement.
  • Si threejs fournissait un fichier d'export à jour avec chaque nouvelle version (énorme effort de maintenance), le compilateur de fermeture détecterait tous les problèmes provenant d'une API changeante (comme ce fut le cas pour Matrix4.makeTranslation ).
  • La configuration du compilateur de fermeture est trop de travail pour moi, car il nécessite un runtime Java. Tous les autres outils nécessaires pour construire ma bibliothèque sont basés sur node/javascript.

Je construis actuellement mon fichier externs.js de bibliothèque de fermeture afin d'intégrer une application THREE.js avec Closure Library. En gros, ce que nous essayons de savoir, c'est :
Existe-t-il une liste quelque part de toutes les classes THREE.js et des méthodes prototypes qu'elles implémentent ? La liste devrait ressembler à ceci :

TROIS.Texture
TROIS.texture.constructeur
TROIS.Texture.clone
TROIS.Texture.dispose
TROIS.DataTexture.clone

(etc...)

Ps-Trois.js est génial, mais avec des jsDocs appropriés, cette liste pourrait être facilement extraite :)

J'ai une mise en œuvre partielle des exportations Three.js ici (écrit manuellement, pourrait donc contenir des erreurs).

@crobi : pourquoi as-tu mis les commentaires du doc ​​dedans ? Cela semble avoir pris beaucoup de temps et je ne suis pas sûr que ce soit nécessaire...

@taoeffect : les commentaires concernent principalement le mode avancé du compilateur de fermeture. J'aime le code fortement typé.

@crobi , oh les commentaires entraînent une saisie forcée ? C'est plutôt cool, je ne savais pas que ça faisait ça.

Uniquement si vous utilisez le compilateur de fermeture pour vérifier les erreurs de type. Similaire à dactylographié . Les deux prétraitent le javascript annoté en javascript simple. Il s'agit donc uniquement d'une vérification au moment de la compilation.

La plupart des commentaires sur le mode d'optimisation avancé de la fermeture ici sont inexacts.

Pour résoudre le problème principal, vous pouvez utiliser l'outil suivant pour générer automatiquement des externes de fermeture pour n'importe quelle bibliothèque http://www.dotnetwise.com/Code/Externs/

De plus, si vous décidez d'utiliser three.js comme entrée dans votre code au lieu de simplement l'utiliser comme bibliothèque externe, vous devrez ajouter le drapeau

--language_in=ECMASCRIPT5

Vous devriez écrire un article de blog à ce sujet, peut-être en prenant une performance
exemple critique et voir s'il est exécuté via la fermeture de Google
compilateur avec de bonnes optimisations fait la différence.
-ben

Le lun. 13 janv. 2014 à 12:31, Rodrigo Formigone <
[email protected]> a écrit :

De plus, si vous décidez d'utiliser three.js comme entrée dans votre code au lieu de
en l'utilisant simplement comme bibliothèque externe, vous devrez ajouter le drapeau

--language_in=ECMASCRIPT5

-
Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps://github.com/mrdoob/three.js/issues/341#issuecomment -32191167
.

Meilleures salutations,
Ben Houston
Voix : 613-762-4113 Skype : ben.exocortex Twitter : @exocortexcom
http://Clara.io - Création de contenu 3D WebGL de qualité professionnelle

Je suppose que je pourrais écrire un tel article. Juste pour clarifier, cependant, la raison pour laquelle on voudrait exécuter Three.js jusqu'à la fermeture (avec ou sans fichier externs) n'est pas nécessairement uniquement pour les optimisations de performances. Closure est principalement destiné à vous aider à écrire du code maintenable en JavaScript (en particulier, des bases de code très volumineuses). L'objectif est d'aider les développeurs à « apprivoiser » JavaScript (en écrivant du JS natif), plutôt que de « l'éviter » (en utilisant GWT ou d'autres outils similaires). Si vous essayez simplement de compiler Three.js dans le cadre d'un projet Closure, le compilateur pourrait vous crier dessus car Three.js pourrait ne pas être conforme à certaines de ses normes (pas assez JSDoc, peut-être ?). L'utilisation de l'indicateur de compilateur --language_in résout ce problème pour le moment, bien que vous receviez quelques avertissements. Si vous souhaitez simplement compiler votre propre code JS, mais référencez Three.js en tant que bibliothèque externe (en laissant ainsi toute la base de code de Three.js intacte et non optimisée), vous aurez besoin du fichier externs mentionné ci-dessus. Sans le fichier externs, Closure lancera des erreurs de compilation indiquant que THREE.* n'est déclaré nulle part, etc.

Bien que je n'écrive pas mon article de blog expliquant comment et pourquoi on pourrait vouloir utiliser Three.js sur un projet de fermeture, voici la meilleure présentation d'introduction sur les outils de fermeture de Google que j'ai vue : (De Google I/O 2011) https://www.youtube.com/watch?v=M3uWx-fhjUc (je sais que c'est une longue vidéo, mais elle explique clairement quel est le but du compilateur et ce que font réellement les différents modes de compilation. Il décrit également pourquoi vous auriez besoin d'un fichier externs).

Bonjour, je suis impatient de développer une application utilisant three.js, et donc de prendre en charge l'option ADVANCED_OPTIMIZATIONS.

La suppression du code mort fonctionne fortement lorsque l'application d'intégration n'utilise qu'une partie des fonctions Three.js.

Actuellement, three.js nécessite que toutes les fonctions soient développées, car l'utilisation prévue se limite à "Just require three.min.js!". Cette approche classique est facile à comprendre, mais pour les codes écrits par cette approche, les minimiseurs JavaScript peuvent réduire le code taille uniquement en réduisant les noms de variables (pas efficace pour les noms de variables courts), en supprimant les espaces (uniquement efficace pour les espaces de retrait, les tabulations et les sauts de ligne) et d'autres astuces bon marché.

En utilisant l'option ADVANCED_OPTIMIZATIONS pour un code "Stylé par un compilateur de fermeture", il peut supprimer l'intégralité des "codes inutiles", qui pèsent principalement sur les grandes bibliothèques. Les bibliothèques comme la bibliothèque Closure étaient devenues volumineuses, mais les utilisateurs et les développeurs de bibliothèques s'en moquent car ils savent que la plupart du code sera supprimé lors de la compilation.

Étant donné que three.js est déjà écrit dans un style orienté objet, je pense qu'il n'est pas (techniquement) difficile de mettre à jour l'intégralité du code en code "Closure compiler styled". Les choses qui m'inquiètent...

  • Le style de compilateur de fermeture nécessite des annotations pour chaque fonction. Actuellement, il n'y en a aucun. Combien de temps faudra-t-il pour ajouter des annotations à toutes les fonctions jamais développées ?
  • Le compilateur de fermeture nécessite des définitions de type strictes. Même pour null et undefined, vous devriez travailler pour eux correctement. Cela peut être un travail difficile pour les fonctions qui ont des paramètres "null-allowed", des paramètres "undefined-allowed", ...
  • Vous devez préparer un fichier externs approprié, si vous avez hâte de préparer la "bibliothèque à version complète" compilée par ADVANCED_OPTIMIZATIONS.

Hai Schedul Xor,

C'est une bonne idée à faire. Pourriez-vous partager un petit extrait, sur la façon dont
cela doit être ajouté à three.js ?

Cordialement,

Ramsundhar Madhavan

Le mar. 24 juin 2014 à 16h23, Schedul Xor [email protected]
a écrit:

Bonjour, je suis impatient de développer une application utilisant three.js, et
donc désireux de prendre en charge l'option ADVANCED_OPTIMIZATIONS.

La suppression du code mort fonctionne fortement lorsque l'application d'intégration utilise uniquement
une partie des fonctions Three.js.

Actuellement, three.js nécessite que chaque fonction soit développée, car le
l'utilisation prévue est limitée à "Juste besoin de three.min.js!".Ce classique
approche est facile à comprendre, mais pour les codes écrits par cette approche,
Les minimiseurs JavaScript peuvent réduire la taille du code uniquement en réduisant les noms de variables
(inefficace pour les noms de variables courts), suppression des espaces (efficace uniquement
pour les espaces de retrait, les tabulations et les sauts de ligne) et d'autres astuces bon marché.

En utilisant l'option ADVANCED_OPTIMIZATIONS pour un "style de compilateur de fermeture"
code, il peut supprimer l'intégralité des "codes non nécessaires", qui pèsent principalement
grandes bibliothèques. Des bibliothèques comme la bibliothèque de fermeture
https://developers.google.com/closure/library/ était devenu volumineux, mais
les utilisateurs de bibliothèques et les développeurs ne s'en soucient pas parce qu'ils savent que
la plupart du code sera supprimé lors de la compilation.

Étant donné que three.js est déjà écrit dans un style orienté objet, je pense que c'est
pas (techniquement) difficile de mettre à jour l'intégralité du code en "Closure compiler
"styled" code. Les choses qui m'inquiètent...

  • Le style de compilateur de fermeture nécessite des annotations pour chaque fonction.
    Actuellement, il n'y en a aucun. Combien de temps faudra-t-il pour ajouter des annotations
    à toutes les fonctions jamais développées ?
  • Le compilateur de fermeture nécessite des définitions de type strictes. Même pour null et
    indéfini, vous devriez travailler pour eux correctement. Cela pourrait être un travail difficile pour
    fonctions qui ont des paramètres "null-allowed", "undefined-allowed"
    paramètres, ...
  • Vous devriez préparer un dossier d'externes approprié, si vous avez hâte
    à préparer la "bibliothèque en version complète" compilée par
    ADVANCED_OPTIMISATIONS.

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/mrdoob/three.js/issues/341#issuecomment-46957189 .

@schedul-xor nous avons vraiment besoin d'aide pour ça... les annotations de code sont-elles vraiment nécessaires ou est-ce suffisant avec les externes ?

Salut,

Je suis nouveau dans cette communauté, je serais intéressé à contribuer à ces
changements.

Cordialement,

Ramsundhar Madhavan

Le mardi 24 juin 2014 à 19h23, Mr.doob [email protected] a écrit :

@schedul-xor https://github.com/schedul-xor nous avons vraiment besoin d'aide
avec ça... les annotations de code sont-elles vraiment nécessaires ou est-ce suffisant avec
externes ?

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/mrdoob/three.js/issues/341#issuecomment-46973166 .

Gardez à l'esprit que les optimisations avancées nécessitent un certain style de codage ou elles casseront votre code. Par exemple, three.js mélange uniforms["diffuse"] et uniforms.diffuse , ce qui n'est pas autorisé dans les optimisations avancées de fermeture. Voir aussi #3222.

L'ajout d'annotations de type strict partout représente une énorme quantité de travail et ajoute de nombreuses lignes de commentaires (dans mon projet, cela a multiplié le nombre de lignes par 2).

Avoir des fichiers externes pour d'autres frameworks/langages Web est agréable.

D'après le tutoriel , les externs sont utilisés pour protéger les variables que vous ne voulez pas renommer. C'est ce que vous utilisez lorsque vous souhaitez protéger (style compilateur sans fermeture) des bibliothèques tierces, en utilisant dans votre projet de style compilateur de fermeture, contre les renommages de variables agressifs.

Je ne sais pas si le compilateur essaiera toujours de couper le code mort même lorsque le fichier externs est la seule chose fournie. Ce sera beaucoup plus facile si vous ne deviez écrire que des fichiers externes, plutôt que d'écrire des annotations sur toutes les fonctions...

Même si, à mon avis, il est préférable d'écrire des annotations pour chaque fonction que d'écrire des externs, car il deviendra difficile de synchroniser le fichier externs par la suite, si le fichier de définition de type et le code source sont différents. Vous pouvez imaginer à quel point ce sera ennuyeux si chaque correctif de fonction nécessite une mise à jour du fichier externe. L'un ou l'autre choix (externes ou /** */ commenter les fonctions) nécessite une annotation, dans la plupart des cas, la méthode la plus simple l'emporte.

Étant donné que three.js est un grand projet, je me demande sur quoi je devrais d'abord travailler. Il vaudra mieux commencer par ce qui peut être fait facilement.

Que diriez-vous de mettre des en-têtes de fichier, de modifier le style de définition de fonction pour chaque fonction ?

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

Il sera plus facile de restreindre tous les types de paramètres et de renvoyer les types de valeur à non null. Cela rendra beaucoup plus facile la transmission des erreurs de compilation ADVANCED_OPTIMIZATIONS.

Hmmm, je ne suis toujours pas très content d'avoir des tonnes de commentaires dans le code. Parfois, je me demande s'il ne serait pas préférable de porter le tout sur quelque chose comme TypeScript à la place (dommage que celui-ci appartienne à Microsoft).

Typescript est beaucoup plus agréable pour le javascript fortement typé que la fermeture. C'est mon expérience après avoir réécrit un chargeur collada de taille moyenne d'abord en javascript compatible avec la fermeture, puis en tapuscrit. Les deux approches ont aidé à trouver des bogues au moment de la compilation. Closure a effectué des optimisations assez intéressantes (inlining, suppression du code mort) de mon code et prend en charge les types nullables. D'un autre côté, l'énorme quantité de commentaires était gênante et la prise en charge de l'IDE (pour la complétion du code) n'était pas aussi bonne qu'avec le tapuscrit. De plus, écrire des classes en tapuscrit est beaucoup plus facile grâce au mot-clé class ECMAScript6.

Mais ce n'est qu'un avis personnel. Plus important encore, je tiens à souligner à nouveau le fait que vous devez vous assurer que tous les accès aux propriétés sont cohérents avant de prendre en charge officiellement la fermeture en mode de compilation avancé. Avoir un fichier externs n'aide pas, l'accès aux propriétés doit être cohérent pour les objets internes qui ne sont pas exportés, puisque vous _voulez_ qu'ils soient renommés/intégrés/supprimés de manière agressive. Vous attraperez des accès incohérents aux propriétés si vous annotez chaque classe et chaque variable, mais cela pour l'ensemble de la base de code three.js prend plusieurs semaines (si j'extrapole le temps qu'il m'a fallu pour annoter mon projet).

Enfin, le portage d'un projet aussi volumineux que three.js vers n'importe quel autre langage/framework/style de codage est quelque chose qui devrait être discuté en détail.

OK, je suis d'accord que three.js est énorme, et donc ajouter des annotations à chaque fonction peut prendre plusieurs semaines. Il pourrait exister de meilleurs AltJS que la fermeture. Cela doit être discuté plus en profondeur (si vous avez hâte de le porter sur autre chose).

Désolé, je ne peux pas attendre. Je vais forker le commit actuel et commencer le portage.

Salut,

Est-il possible d'automatiser l'ajout de ces annotations ? Si oui, nous pouvons les ajouter
à build.py et à ajouter juste avant d'activer l'optimisation avancée de la fermeture.

Cordialement,

Ramsundhar Madhavan

Le mer. 25 juin 2014 à 6h05, Schedul Xor [email protected]
a écrit:

OK, je suis d'accord que three.js est énorme, et donc ajouter des annotations à chacun
fonctions peuvent prendre plusieurs semaines. Il pourrait exister de meilleurs AltJS que
fermeture. Cela doit être discuté (si vous avez hâte de le porter sur
autre chose) plus profondément.

Désolé, je ne peux pas attendre. Je vais forker le commit actuel et commencer le portage.

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/mrdoob/three.js/issues/341#issuecomment -47047966.

@ ramsundhar20 , à mon avis, ajouter d'abord des annotations (inexactes? mieux que rien. pas un gros problème. il peut être mis à jour) rendra l'automatisation beaucoup plus facile.

Three.js contient actuellement 163 fichiers javascript avec 1354 fonctions définies. Oui c'est énorme, mais ce n'est pas un objectif qui est trop loin.

// J'ai peur si ce sujet n'est pas à sa place...

@schedul-xor encore, je ne suis pas vraiment fan d'avoir un commentaire par fonction :/

@mrdoob OK, j'ai compris.

En respectant votre politique, j'aimerais ajouter des commentaires par fonction uniquement dans mon fork. De plus, je ne ferai jamais de pull request. Au lieu de cela, je porterai les modifications originales de three.js sur mon fork de style fermeture. Votre considération favorable serait appréciée.

Ça sonne bien :)

Merci! Je vais commencer à travailler dessus.

Existe-t-il au moins un fichier externe de base three.js à utiliser avec le compilateur de fermeture ? Cela ne nécessite pas que le code source de Three.js ait des annotations de style google supplémentaires, c'est juste pour faire le lien à partir d'un app.js externe qui utilise three.js suffisamment compilable/obscurci?

Je suis également très intéressé par un fichier externe complet et de qualité pour three.js. En voici un, mais il n'est pas complet :

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

Je suppose qu'une façon de procéder consiste à commencer par celui-ci et à ajouter manuellement les éléments que vous utilisez.

Oui, comptez mon vote. Idéalement pour un threejs 100 % typé compilable en mode avancé - ou pour le moins un fichier externs.

L'inférence de type s'est améliorée et l'encombrement requis a diminué. Avec des portées et des alias en place, le code n'a pas à être lu aussi détaillé que la bibliothèque de fermeture. Cela revient à peu près à écrire des documents en ligne tapés en cas de code propre. Sont-ils vraiment assez mauvais pour l'emporter sur tous les avantages ?

Les paramètres super agressifs, c'est-à-dire le mode avancé + la compression JS + les optimisations basées sur le type, ne supprimeront pas seulement le code mort, mais pourront faire tout ce qu'un compilateur d'optimisation peut faire :

Les constantes / énumérations nommées seront remplacées par des chiffres. En outre, le compilateur peut tracer la constance, effectuer des calculs avec d'autres constantes et enfin insérer un nombre clair là où il est nécessaire. Le contrôle de flux dépendant est bien sûr soumis à l'élimination du code mort. Les fonctions qui n'ont qu'un seul site d'appel actif dans l'application résultante et celles dont la forme compressée finira par être plus petite que leur définition seraient sauvegardées. Les espaces de noms sont supprimés. Tous les noms non protégés sont réduits au minimum.

La recherche est relativement chère en JavaScript. La combinaison du renommage, du pliage constant et de l'inline supprimera beaucoup de recherches ainsi que de nombreux appels de fonction. En plus de cela, étant donné un en-tête approprié (il y en a un dans la bibliothèque de fermeture), toutes les constantes WebGL standardisées peuvent être intégrées dans le moteur de rendu.

Le résultat est une bibliothèque plus petite, plus rapide, auto-documentée et automatiquement personnalisable. Le compilateur détectera également beaucoup plus de bogues avec des paramètres plus agressifs - cela facilitera probablement la révision du code. Enfin et surtout, il y a l'effet d'obscurcissement : le regroupement du code client avec la bibliothèque personnalisée offre une bien meilleure protection contre le vol de propriété intellectuelle que le code avec des symboles révélateurs qui ont été conservés au moyen d'un fichier externe.

Je ne trouve pas la branche mentionnée ci-dessus. Est-ce que quelqu'un travaille encore sur une version dactylographiée ?

@mrdoob Un espoir de changement d'avis concernant la ligne principale ?

Je serais heureux de vous aider.

@mrdoob Un espoir de changement d'avis concernant la ligne principale ?

En ce moment, je me concentre sur la refactorisation de WebGLRenderer 😇

Peut changer les constantes en const plutôt que var a un bon support pour tous les navigateurs WebGL https://kangax.github.io/compat-table/es6/ (const->basic) et js les moteurs commencent à optimiser pour const Accélération des constantes globales à l'aide de l'optimisation de champ fixe

Intéressant, cependant, car cela ne fonctionne qu'à la place de var , ne s'appliquant qu'à une très petite fraction des cas dont je parle - même s'il ne s'agit que de constantes. De plus, les compilateurs JIT sont pressés par définition, ils ne peuvent donc naturellement pas rivaliser avec les optimisations de programme entières effectuées par un outil hors ligne. Chaque moteur JS doit respecter la structure du code et ne peut pas le refactoriser arbitrairement car nous nous attendons à pouvoir par exemple ouvrir la console et trouver le programme que nous y avons mis, remplacer une fonction spécifique, etc.

Retour à la prise en charge du compilateur de fermeture : j'ai fait quelques lectures et expérimentations. Voici ce que j'ai découvert :

  • Aucune annotation n'est requise pour exécuter le mode avancé,
  • des annotations peuvent être ajoutées progressivement pour augmenter le niveau d'optimisation, et
  • le chargeur a besoin de quelques soins pour continuer à fonctionner, mais c'est assez facile.

Il existe essentiellement trois cas d'utilisation différents :

  1. Les modèles peuvent être compressés avec l'application et la bibliothèque.
  2. L'application et la bibliothèque sont compressées. Les modèles sont chargés au moment de l'exécution.
  3. La bibliothèque est compilée en mode basique et une application en mode avancé veut l'utiliser.

Le troisième nécessite un fichier externe pour tous les Three.js et représente beaucoup de travail pour trop peu d'avantages pour l'OMI. Je ne parlerai donc que des deux premiers - ce sont les préférés, de toute façon :

Lorsque le compilateur voit

anObject['aProperty']

il ne touchera pas au nom de la propriété (aucune chaîne n'est jamais modifiée).

anObject.aProperty

d'autre part, permet au compilateur de renommer systématiquement la propriété, à moins qu'il ne sache que anObject est externe à l'application en cours de compilation. Le compilateur le sait à partir des _externs_ intégrés ou fournis explicitement.

Voici la recette :

  • Nous faisons en sorte que le chargeur accède systématiquement aux propriétés en utilisant la notation par points.
  • Nous tapons l'entrée et écrivons un fichier externe uniquement pour le JSON .
  • La compilation avec ce fichier externs devrait suffire pour que le cas d'utilisation 2 fonctionne.
  • Pour le cas d'utilisation 1, nous n'utilisons pas le fichier externs, mais supprimons à la place les guillemets des clés d'objet dans le JSON :
{
    "camera": {
        "object": {
    // ...

deviendrait simplement

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

Assez simple, n'est-ce pas?

Le cas d'utilisation 1 devient encore plus attrayant lorsque le format JSON autoriserait des données binaires externes (brutes ou compressées via webgl-loader ou o3dgc) - techniquement une autre fonctionnalité complètement orthogonale à la prise en charge de la fermeture, bien sûr.

Le fichier externs peut également remplacer les pages Wiki toujours obsolètes documentant le format de fichier :-).

Je sais que ce problème est clos depuis un certain temps. Cependant, j'ai récemment eu le même problème en utilisant three.js dans un projet de compilateur de fermeture et j'ai atterri sur cette page. J'ai écrit un outil qui transforme les .d.ts (fichiers de déclaration dactylographiés) en un fichier compilateur de fermeture. En utilisant l'outil et le grand fichier descripteur DefinitelyTyped/threejs décrit, cela fonctionne parfaitement.
L'outil : https://github.com/eredo/tsd2cce ou installer via npm install -g tsd2cce

J'espère que cela t'aides...

@eredo qui m'a totalement aidé. Tous les autres générateurs que j'ai essayés manquaient un bon nombre de définitions de méthodes pour la bibliothèque three.js. Merci!

@eredo @Corkle ou quelqu'un d'autre, pouvez-vous nous montrer comment utiliser tsd2cce ? Le premier argument est clairement le fichier de définition .d.ts, mais quel est le deuxième argument ? Je reçois ce problème. https://github.com/eredo/tsd2cce/issues/6

En fait, j'ai trouvé que l'utilisation du r73 d.ts de février fonctionne bien avec tsd2cce, r73 est cependant trop vieux pour moi.

La bonne façon de le faire maintenant serait d'utiliser tsickle pour générer à partir des fichiers d.ts.

Salut à tous,

Pour la postérité et le bénéfice de tous, j'ai décidé de rendre compte ici de mes propres tentatives pour réduire davantage la bibliothèque avec les ADVANCED_OPTIMIZATIONS de Google Closure Compiler et d'autres ajustements.

J'ai créé un extern.js qui autorise Three.min.js avec des optimisations avancées activées. C'est LOIN d'être parfait.

Pour le créer, j'ai commencé avec un extern.js basé sur des exemples précédents dans ce fil. La bibliothèque était cassée lors de la compilation de cette façon à cause de propriétés mutilées non incluses dans ce fichier externe. En utilisant l'option --property_renaming_report sur le compilateur de fermeture, j'ai obtenu la liste complète des propriétés mutilées. Après avoir ajouté TOUTES ces propriétés au fichier extern.js, les propriétés n'étaient plus mutilées et la sortie était la même que SIMPLE_OPTIMIZATIONS. À partir de là, j'ai commencé à commenter des sections de extern.js de manière sélective/manuelle et à confirmer que la bibliothèque fonctionnait toujours sous une forme minifiée.

J'adorerais automatiser cette estimation et vérifier et obtenir un extern.js parfait qui détruira en toute sécurité autant de noms de propriétés que possible. J'ai eu l'idée d'utiliser les tests unitaires pour THREE.JS et de déterminer par programmation quels noms de domaine mutilés ont entraîné l'échec des tests, mais il ne semble pas possible d'exécuter les tests unitaires à partir de la ligne de commande actuellement, par exemple avec phantomjs. (Probablement à cause de WebGL) ?

Quoi qu'il en soit, il s'agit d'un « progrès » vers une bibliothèque réduite plus petite, ce qui m'aide à réduire la taille globale de ma javascript SPA.

externs.js

mise à jour de la commande de fermeture de build package.json

J'ai également utilisé des commandes de remplacement de chaîne pour supprimer tous les messages console.warn et console.error de la bibliothèque, comme vous pouvez le voir dans la commande build-closure. Avec cela, et en commentant certaines sections de code, j'ai réduit la bibliothèque minifiée d'environ 20% jusqu'à présent, et il y a place à l'amélioration.

@mrdoob En faisant quelque chose comme ma méthode ici, vous pourriez éventuellement fournir un extern.js qui permet des ADVANCED_OPTIMIZATIONS sans encombrer le code avec des annotations spécifiques à ce compilateur, ce qui semblait être votre principale préoccupation.

@medmr1 Génial ! Avez-vous essayé de compiler votre application avec la bibliothèque three.js tout en un ? Cela éviterait idéalement le besoin d'un fichier externe.

Je n'ai pas essayé de tout construire dans la fermeture, non. Cela peut fonctionner correctement, mais je soupçonne qu'il y aura toujours des problèmes concernant la modification de certaines propriétés auxquelles il est fait référence par programme ? IE trucs comme var thing = ShaderLib[ shaderType + "BumpMapFrag"] Mais peut-être que je m'épargnerais bien des ennuis ?

Oui, quelque chose comme var thing = ShaderLib[ shaderType + "BumpMapFrag"] va rompre avec les optimisations avancées. les références de propriété doivent être analysables de manière statique. Vous pourriez faire quelque chose comme :

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

Construire un fichier externe correct est certainement plus bénéfique pour le projet dans son ensemble car la plupart des gens ne compileront pas leur application avec Closure Compiler, utiliseront uniquement la version minifiée publiée.

Au lieu d'externes, vous pouvez également essayer l'annotation @export .
https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#export -export-sometype

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

Questions connexes

zsitro picture zsitro  ·  3Commentaires

scrubs picture scrubs  ·  3Commentaires

ghost picture ghost  ·  3Commentaires

donmccurdy picture donmccurdy  ·  3Commentaires

fuzihaofzh picture fuzihaofzh  ·  3Commentaires