Le compilateur de fermeture est un outil pour faire du téléchargement JavaScript et s'exécuter plus rapidement. C'est un véritable compilateur pour JavaScript. Au lieu de compiler d'un langage source au code machine, il compile de JavaScript à un meilleur javascript. Il analyse votre javascript, l'analyse, supprime le code mort et réécrit et minimise ce qui reste. Il vérifie également la syntaxe, les références de variables et les types et met en garde contre les pièges JavaScript communs.
Les modes de compilation autres que ADVANCED
ont toujours été une réflexion après coup et nous avons obsolète ces modes. Nous pensons que d'autres outils fonctionnent de manière comparable pour les modes non ADVANCED
et sont mieux intégrés dans l'écosystème JS plus large.
Le compilateur de fermeture ne convient pas au JavaScript arbitraire. Pour que le mode ADVANCED
génére des JavaScript en activité, le code d'entrée JS doit être écrit en pensant à la fermeture-compositeur.
Le compilateur de fermeture est un optimiseur "World". Il s'attend à voir directement ou au moins à recevoir des informations sur chaque utilisation possible de chaque variable globale ou exportée et de chaque nom de propriété.
Il supprimera et renommera agressivement les variables et les propriétés afin de rendre le code de sortie aussi petit que possible. Cela se traduira par une sortie brisée JS, si les utilisations des variables ou des propriétés globales en sont cachées.
Bien que l'on puisse rédiger des fichiers Externs personnalisés pour dire au compilateur de laisser certains noms inchangés afin qu'ils puissent être accessibles en toute sécurité par le code qui ne fait pas partie de la compilation, cela est souvent fastidieux à maintenir.
Le renommer de la propriété du compilateur de fermeture vous oblige à accéder systématiquement à une propriété avec obj[p]
ou obj.propName
, mais pas les deux.
Lorsque vous accédez à une propriété avec des crochets (par exemple obj[p]
) ou en utilisant une autre méthode indirecte comme let {p} = obj;
Cela cache le nom littéral de la propriété référencée du compilateur. Il ne peut pas savoir si obj.propName
fait référence à la même propriété que obj[p]
. Dans certains cas, il remarquera ce problème et arrêtera la compilation avec une erreur. Dans d'autres cas, il renommera propName
à quelque chose de plus court, sans remarquer ce problème, entraînant un code JS de sortie brisé.
Le compilateur de fermeture inclinera de manière agressive les variables globales et les chaînes globales des noms de propriétés sur les variables globales (par exemple myFoo.some.sub.property
-> myFoo$some$sub$property
.
Il essaie de reculer de cela ou de s'arrêter avec une erreur lorsque cela générera une sortie JS cassée, mais il y a des cas où il ne reconnaîtra pas le problème et générera simplement des JS cassés sans avertissement. Cela est beaucoup plus susceptible de se produire dans le code qui n'a pas été explicitement écrit avec le compilateur de fermeture à l'esprit.
Le compilateur de fermeture et les externes qu'il utilise par défaut supposent que l'environnement cible est une fenêtre de navigateur Web.
Les travailleurs Web sont également pris en charge, mais le compilateur ne vous avertira probablement pas si vous essayez d'utiliser des fonctionnalités qui ne sont pas réellement disponibles pour un travailleur Web.
Certains fichiers et fonctionnalités externes ont été ajoutés au compilateur de fermeture pour prendre en charge l'environnement NodeJS, mais ils ne sont pas activement pris en charge et ne fonctionnaient jamais très bien.
JavaScript qui n'utilise pas le goog.module()
et goog.require()
de base.js
pour déclarer et utiliser les modules n'est pas bien pris en charge.
La syntaxe import
et export
ECMAScript n'existait qu'en 2015. Le compilateur de fermeture et closure-library
ont développé leurs propres moyens pour déclarer et utiliser des modules, et cela reste le seul moyen bien pris en charge de définir des modules.
Le compilateur met en œuvre une certaine compréhension des modules ECMascript, mais la modification des projets de Google pour utiliser la nouvelle syntaxe n'a jamais offert un avantage qui valait le coût du changement. Le code TypeScript de Google utilise des modules ECMAScript, mais ils sont convertis en syntaxe goog.module()
avant que la fermeture-compositeur ne les voit. Ainsi, effectivement, la prise en charge des modules ECMAScript n'est pas utilisée dans Google. Cela signifie que nous sommes peu susceptibles de remarquer ou de corriger les bogues dans la prise en charge des modules ECMascript.
La prise en charge des modules CommonJS en tant qu'entrée a été ajoutée dans le passé, mais n'est pas utilisée dans Google, et devrait être entièrement supprimée en 2024.
Le compilateur de fermeture est utilisé par Google Projects pour:
Réduisez considérablement la taille du code des très grandes applications JavaScript
Vérifiez le code JS pour les erreurs et la conformité aux meilleures pratiques générales et / ou spécifiques au projet.
Définissez les messages visibles utilisateur d'une manière qui permet de les remplacer par des versions traduites pour créer des versions localisées d'une application.
Transplier les fonctionnalités JS plus récentes dans un formulaire qui fonctionnera sur des navigateurs qui manquent de prise en charge de ces fonctionnalités.
Brisez l'application de sortie en morceaux qui peuvent être chargés individuellement au besoin.
Remarque: ces morceaux sont des scripts JavaScript simples. Ils n'utilisent pas la syntaxe import
et export
ECMAScript.
Pour atteindre ces objectifs, le compilateur de fermeture place de nombreuses restrictions sur sa contribution:
Utilisez goog.module()
et goog.require()
pour déclarer et utiliser des modules.
La prise en charge de la syntaxe import
et export
ajoutée dans ES6 n'est pas activement maintenue.
Utilisez des annotations dans les commentaires pour déclarer les informations de type et fournir des informations dont le compilateur a besoin pour éviter de casser certains modèles de code (par exemple @nocollapse
et @noinline
).
Soit utiliser uniquement Dot-Access (par exemple object.property
) ou utiliser uniquement l'accès dynamique (par exemple object[propertyName]
ou Object.keys(object)
) pour accéder aux propriétés d'un type d'objet particulier.
Les mélanges masqueront certaines utilisations d'une propriété du compilateur, ce qui entraîne un code de sortie brisé lorsqu'il renommera la propriété.
En général, le compilateur prévoit de voir une application entière comme une seule compilation. Les interfaces doivent être construites soigneusement et explicitement afin de permettre l'interopération avec le code en dehors de l'unité de compilation.
Le compilateur suppose qu'il peut voir toutes les utilisations de toutes les variables et propriétés et les renommera librement ou les supprimera s'ils semblent inutilisés.
Utilisez des fichiers externes pour informer le compilateur de toute variable ou propriété qu'il ne doit pas supprimer ou renommer.
Il existe des fichiers externes par défaut déclarant les API Global JS et Dom standard. Des fichiers plus externes sont nécessaires si vous utilisez des API moins courantes ou si vous attendez un code JavaScript externe pour accéder à une API dans le code que vous composez.
La façon la plus simple d'installer le compilateur est avec le NPM ou le fil:
yarn global add google-closure-compiler
# OR
npm i -g google-closure-compiler
Le gestionnaire de packages liera le binaire pour vous, et vous pouvez accéder au compilateur avec:
google-closure-compiler
Cela démarre le compilateur en mode interactif. Taper:
var x = 17 + 25 ;
Appuyez sur Enter
, puis Ctrl+Z
(sur Windows) ou Ctrl+D
(sur Mac / Linux), puis Enter
à nouveau. Le compilateur répondra avec la sortie compilée (en utilisant le mode SIMPLE
par défaut):
var x = 42 ;
Une version pré-compilée du compilateur est également disponible via Maven.
Le compilateur de fermeture propose de nombreuses options de lecture des entrées d'un fichier, d'écriture de sortie vers un fichier, de vérifier votre code et d'exécuter des optimisations. Voici un exemple simple de compression d'un programme JS:
google-closure-compiler --js file.js --js_output_file file.out.js
Nous tirons le meilleur parti du compilateur si nous lui donnons tout notre code source (voir compilation plusieurs scripts), ce qui nous permet d'utiliser des optimisations ADVANCED
:
google-closure-compiler -O ADVANCED rollup.js --js_output_file rollup.min.js
Remarque: La sortie ci-dessous est juste un exemple et n'est pas mise à jour. La page Wiki Flags and Options est mise à jour lors de chaque version.
Pour voir toutes les options du compilateur, Type:
google-closure-compiler --help
--flag | Description |
---|---|
--compilation_level (-O) | Spécifie le niveau de compilation à utiliser. Options: BUNDLE , WHITESPACE_ONLY , SIMPLE (par défaut), ADVANCED |
--env | Détermine l'ensemble des externes intégrés à charger. Options: BROWSER , CUSTOM . Par défaut est BROWSER . |
--externs | Le fichier contenant javascript externs. Vous pouvez spécifier plusieurs |
--js | Le nom de fichier JavaScript. Vous pouvez spécifier plusieurs. Le nom du drapeau est facultatif, car les args sont interprétés comme des fichiers par défaut. Vous pouvez également utiliser des modèles de glob de style minimatch. Par exemple, utilisez --js='**.js' --js='!**_test.js' pour inclure récursivement tous les fichiers JS qui ne se terminent pas dans _test.js |
--js_output_file | Nom de fichier de sortie primaire. Si elle n'est pas spécifiée, la sortie est écrite sur stdout. |
--language_in | Définit la spécification linguistique à laquelle les sources d'entrée devraient se conformer. Options: ECMASCRIPT3 , ECMASCRIPT5 , ECMASCRIPT5_STRICT , ECMASCRIPT_2015 , ECMASCRIPT_2016 ECMASCRIPT_NEXT ECMASCRIPT_2017 , ECMASCRIPT_2018 , STABLE , ECMASCRIPT_2019 |
--language_out | Définit la spécification linguistique à laquelle la sortie doit se conformer. Options: ECMASCRIPT3 , ECMASCRIPT5 , ECMASCRIPT5_STRICT , ECMASCRIPT_2015 , ECMASCRIPT_2016 , ECMASCRIPT_2017 , ECMASCRIPT_2018 , ECMASCRIPT_2019 , STABLE |
--warning_level (-W) | Spécifie le niveau d'avertissement à utiliser. Options: QUIET , DEFAULT , VERBOSE |
Vous pouvez accéder au compilateur dans un programme JS en important google-closure-compiler
:
import closureCompiler from 'google-closure-compiler' ;
const { compiler } = closureCompiler ;
new compiler ( {
js : 'file-one.js' ,
compilation_level : 'ADVANCED'
} ) ;
Ce package fournira un accès programmatique au binaire Graal natif dans la plupart des cas, et retombera dans la version Java autrement.
Si vous avez plusieurs scripts, vous devez les compiler tous avec une commande compile.
google-closure-compiler in1.js in2.js in3.js --js_output_file out.js
Vous pouvez également utiliser des globs de style minimatch.
# Recursively include all js files in subdirs
google-closure-compiler ' src/**.js ' --js_output_file out.js
# Recursively include all js files in subdirs, excluding test files.
# Use single-quotes, so that bash doesn't try to expand the '!'
google-closure-compiler ' src/**.js ' ' !**_test.js ' --js_output_file out.js
Le compilateur de fermeture concatera les fichiers dans l'ordre où ils sont passés sur la ligne de commande.
Si vous utilisez des globes ou de nombreux fichiers, vous pouvez commencer à rencontrer des problèmes de gestion des dépendances entre les scripts. Dans ce cas, vous devez utiliser le lib / base.js inclus qui fournit des fonctions pour appliquer les dépendances entre les scripts (à savoir goog.module
et goog.require
). Le compilateur de fermeture réorganisera automatiquement les entrées.
Le compilateur de fermeture verse avec lib / base.js qui fournit des fonctions et variables JavaScript qui servent de primitives permettant certaines caractéristiques du compilateur de fermeture. Ce fichier est une dérivée de la base de base.js nommée identique dans la bibliothèque de fermeture qui sera bientôt obsolète. Cette base.js
sera prise en charge par le compilateur de fermeture à l'avenir et peut recevoir de nouvelles fonctionnalités. Il a été conçu pour conserver uniquement ses pièces de base perçues.
Pour construire le compilateur vous-même, vous aurez besoin de ce qui suit:
Condition préalable | Description |
---|---|
Java 11 ou plus tard | Utilisé pour compiler le code source du compilateur. |
Nodejs | Utilisé pour générer des ressources utilisées par la compilation Java |
Git | Utilisé par Bazel pour télécharger les dépendances. |
Bazélisque | Utilisé pour construire les différentes cibles du compilateur. |
Bazelisk est un wrapper autour de Bazel qui charge dynamiquement la version appropriée de Bazel pour un référentiel donné. L'utiliser empêche les erreurs parasites qui résultent de l'utilisation de la mauvaise version de Bazel pour construire le compilateur, ainsi que facilite l'utilisation de différentes versions Bazel pour d'autres projets.
Bazelisk est disponible auprès de nombreux gestionnaires de packages. N'hésitez pas à utiliser le plus à l'aise.
Instructions pour installer Bazelisk.
$ bazelisk build //:compiler_uberjar_deploy.jar
# OR to build everything
$ bazelisk build //:all
Les tests peuvent être exécutés de manière similaire. La commande suivante exécutera tous les tests dans le repo.
$ bazelisk test //:all
Il y a des centaines d'objectifs de test individuels, il faudra donc quelques minutes pour les exécuter tous. Pendant le développement, il est généralement préférable de spécifier les tests exacts qui vous intéressent.
bazelisk test //: $path_to_test_file
Voir les intégrations Bazel IDE.
Une fois le compilateur construit, le pot compilé sera dans le bazel-bin/
répertoire. Vous pouvez y accéder avec un appel à java -jar ...
ou en utilisant le script package.json:
# java -jar bazel-bin/compiler_uberjar_deploy.jar [...args]
yarn compile [...args]
src/com/google/javascript/jscomp/CommandLineRunner.java
ou créez votre propre version étendue de la classe.Cependant, vous choisissez de contribuer, veuillez respecter notre code de conduite pour maintenir notre communauté un endroit sain et accueillant.
Copyright 2009 Les auteurs du compilateur de fermeture.
Licencié sous la licence Apache, version 2.0 (la "licence"); Vous ne pouvez pas utiliser ce fichier sauf conforme à la licence. Vous pouvez obtenir une copie de la licence à http://www.apache.org/licenses/license-2.0.
Sauf exiger la loi applicable ou convenu par écrit, les logiciels distribués en vertu de la licence sont distribués sur une base «tel quel», sans garantie ou conditions d'aucune sorte, expresse ou implicite. Voir la licence pour la langue spécifique régissant les autorisations et les limitations sous la licence.
Chemin de code | src/com/google/javascript/rhino , test/com/google/javascript/rhino |
URL | https://developer.mozilla.org/en-us/docs/mozilla/projects/rhino |
Version | 1.5R3, avec de lourdes modifications |
Licence | Licence publique NetScape et MPL / GPL Dual Licence |
Description | Une copie partielle de Mozilla Rhino. Mozilla Rhino est une implémentation de JavaScript pour le JVM. Les structures de données d'arbre d'analyse JavaScript ont été extraites et modifiées de manière significative pour une utilisation par le compilateur JavaScript de Google. |
Modifications locales | Les packages ont été renommés. Tout le code non pertinent pour l'arborescence d'analyse a été supprimé. Un analyseur JSDOC et un système de typage statique ont été ajoutés. |
URL | http://args4j.kohsuke.org/ |
Version | 2.33 |
Licence | Mit |
Description | Args4j est une petite bibliothèque de classe Java qui facilite l'analyse des options / arguments de ligne de commande dans votre application CUI. |
Modifications locales | Aucun |
URL | https://github.com/google/guava |
Version | 31.0.1 |
Licence | Licence Apache 2.0 |
Description | Les principales bibliothèques Java de Google. |
Modifications locales | Aucun |
URL | https://github.com/findbugsproject/findbugs |
Version | 3.0.1 |
Licence | Licence BSD |
Description | Annotations pour la détection des défauts logiciels. |
Modifications locales | Aucun |
URL | http://junit.org/junit4/ |
Version | 4.13 |
Licence | Licence publique commune 1.0 |
Description | Un cadre pour écrire et exécuter des tests automatisés en Java. |
Modifications locales | Aucun |
URL | https://github.com/google/protobuf |
Version | 3.0.2 |
Licence | Nouvelle licence BSD |
Description | Soutenir les bibliothèques pour les tampons de protocole, un codage de données structurées. |
Modifications locales | Aucun |
URL | https://github.com/google/re2j |
Version | 1.3 |
Licence | Nouvelle licence BSD |
Description | Expression régulière du temps linéaire correspondant à Java. |
Modifications locales | Aucun |
URL | https://github.com/google/truth |
Version | 1.1 |
Licence | Licence Apache 2.0 |
Description | Framework Assertion / Proposition pour les tests unitaires Java |
Modifications locales | Aucun |
URL | https://ant.apache.org/bindownload.cgi |
Version | 1.10.11 |
Licence | Licence Apache 2.0 |
Description | Ant est un outil de construction basé sur Java. En théorie, c'est un peu comme "faire" sans les rides de Make et avec la pleine portabilité du code Java pur. |
Modifications locales | Aucun |
URL | https://github.com/google/gson |
Version | 2.9.1 |
Licence | Licence Apache 2.0 |
Description | Une bibliothèque Java pour convertir JSON en objets Java et vice-versa |
Modifications locales | Aucun |
Chemin de code | contrib/nodejs |
URL | https://github.com/dcodeio/node.js-closure-compiler-externs |
Version | E891B4FBCF5F466CC4307B0FA842A7D8163A073A |
Licence | Licence Apache 2.0 |
Description | Type Contracts pour les API NodeJS |
Modifications locales | Des changements substantiels pour les rendre compatibles avec NPMCommandlinerUnner. |