Der Verschluss -Compiler ist ein Tool, um JavaScript schneller herunterzuladen und zu ausgeführt zu werden. Es ist ein echter Compiler für JavaScript. Anstatt von einer Quellsprache zu Maschinencode zu kompilieren, werden von JavaScript zu einem besseren JavaScript kompiliert. Es analysiert Ihr JavaScript, analysiert es, beseitigt tote Code und schreibt um und minimiert, was noch übrig ist. Es überprüft auch die Syntax, variable Referenzen und Typen und warnt vor gemeinsamen JavaScript -Fallstricken.
Zusammenstellungsmodi als ADVANCED
waren immer ein nachträglicher Gedanke, und wir haben diese Modi veraltet. Wir glauben, dass andere Tools für nicht ADVANCED
Modi vergleichsweise funktionieren und besser in das breitere JS-Ökosystem integriert sind.
Der Verschlusskompiler eignet sich nicht für willkürliche JavaScript. Damit ADVANCED
Modus funktionierender JavaScript generiert, muss der Eingabe-JS-Code mit dem Schluss-Kompilierer geschrieben werden.
Der Verschluss -Compiler ist ein Optimierer der ganzen Welt. Es wird erwartet, dass sie direkt Informationen über jede mögliche Verwendung jeder globalen oder exportierten Variablen und jeden Eigenschaftsnamen sehen oder zumindest empfangen.
Es wird aggressiv Variablen und Eigenschaften entfernen und umbenennen, um den Ausgabescode so klein wie möglich zu gestalten. Dies führt zu einer zerbrochenen Ausgabe -JS, wenn die Verwendung globaler Variablen oder Eigenschaften vor ihr versteckt ist.
Obwohl man benutzerdefinierte EXTERNS -Dateien schreiben kann, um dem Compiler zu sagen, er solle einige Namen unverändert hinterlassen, damit er sicher durch Code zugegriffen werden kann, auf die nicht Teil der Kompilierung ist, ist dies häufig mühsam zu pflegen.
Um die Umbenennung von Clospiler -Compiler -Eigenschaften zu erhalten, müssen Sie mit obj[p]
oder obj.propName
konsequent auf eine Eigenschaft zugreifen, aber nicht beides.
Wenn Sie auf eine Eigenschaft mit quadratischen Klammern zugreifen (z. B. obj[p]
) oder eine andere indirekte Methode wie let {p} = obj;
Dies verbirgt den wörtlichen Namen des Eigentums, auf das der Compiler verwiesen wird. Es kann nicht wissen, ob sich obj.propName
auf dieselbe Eigenschaft wie obj[p]
bezieht. In einigen Fällen wird dieses Problem bemerken und die Kompilierung mit einem Fehler stoppen. In anderen Fällen wird propName
in etwas Kürzeres umbenannt, ohne dieses Problem zu bemerken, was zu einem JS -Code für einen kaputten Ausgangscode führt.
Der Verschluss -Compiler findet aggressiv globale Variablen ein und flacht die Ketten von Eigenschaftsnamen in globalen Variablen (z. B. myFoo.some.sub.property
-> myFoo$some$sub$property
), um sie leichter zu erleichtern, um unbenutzten Code zu erkennen.
Es wird versucht, dies entweder davon abzuwehren oder mit einem Fehler zu stoppen, wenn dies bei der Ausgabe eine kaputte JS -Ausgabe erzeugt, aber es gibt Fälle, in denen es das Problem nicht erkennen und einfach ohne Vorwarnung kaputte JS erzeugt. Dies ist viel wahrscheinlicher, dass in Code, der nicht explizit unter Berücksichtigung des Verschluss -Compilers geschrieben wurde, nicht ausdrücklich geschrieben wurde.
Der Verschluss -Compiler und die externen, die standardmäßig verwendet werden, gehen davon aus, dass die Zielumgebung ein Webbrowserfenster ist.
Webworker werden ebenfalls unterstützt, aber der Compiler wird Sie wahrscheinlich nicht warnen, wenn Sie versuchen, Funktionen zu verwenden, die einem Webworker nicht zur Verfügung stehen.
Einige externe Dateien und Funktionen wurden dem Clossure -Compiler hinzugefügt, um die NodeJS -Umgebung zu unterstützen, sie werden jedoch nicht aktiv unterstützt und funktionieren nie sehr gut.
JavaScript, das nicht die goog.module()
und goog.require()
von base.js
verwendet, um Module zu deklarieren und zu verwenden, wird nicht gut unterstützt.
Die ECMAScript- import
und export
bestand erst 2015. Der Verschluss-Compiler und closure-library
entwickelten ihre eigenen Mittel zur Deklaration und Verwendung von Modulen, und dies bleibt die einzig gut unterstützte Methode zur Definition von Modulen.
Der Compiler implementiert ein gewisses Verständnis der ECMASScript -Module, aber die Änderung von Googles Projekten zur Nutzung der neueren Syntax hat nie einen Vorteil angeboten, der die Kosten für die Änderung wert war. Der TypeScript-Code von Google verwendet ECMASScript-Module, werden jedoch in syntax goog.module()
konvertiert, bevor die Verschlusskompiler sie sieht. Daher ist die Unterstützung von ECMAScript -Modulen effektiv in Google nicht verwendet. Dies bedeutet, dass es unwahrscheinlich ist, dass wir Fehler in der Unterstützung für ECMAScript -Module bemerken oder beheben.
Die Unterstützung für CommonJS -Module als Eingabe wurde in der Vergangenheit hinzugefügt, wird jedoch in Google nicht verwendet und wird wahrscheinlich irgendwann im Jahr 2024 vollständig entfernt.
Der Verschluss -Compiler wird von Google Projects verwendet, um:
Reduzieren Sie drastisch die Codegröße sehr großer JavaScript -Anwendungen
Überprüfen Sie den JS-Code auf Fehler und die Konformität mit allgemeinen und/oder projektspezifischen Best Practices.
Definieren Sie benutzerfreundliche Nachrichten auf eine Weise, die es ermöglicht, sie durch übersetzte Versionen zu ersetzen, um lokalisierte Versionen einer Anwendung zu erstellen.
Transpile neuere JS -Funktionen in ein Formular, das auf Browsern ausgeführt wird, die für diese Funktionen fehlen.
Unterteilen Sie die Ausgangsanwendung in Stücke, die bei Bedarf einzeln geladen werden können.
Hinweis: Diese Brocken sind einfache JavaScript -Skripte. Sie verwenden die ECMAScript import
und export
nicht.
Um diese Ziele zu erreichen, legt der Compiler viele Einschränkungen für die Eingabe ein:
Verwenden Sie goog.module()
und goog.require()
um Module zu deklarieren und zu verwenden.
Die Unterstützung der in ES6 hinzugefügten import
und export
wird nicht aktiv aufrechterhalten.
Verwenden Sie Annotationen in Kommentaren, um Informationen zu deklarieren und Informationen bereitzustellen, die der Compiler benötigt, um das Brechen einiger Codemuster (z. B. @nocollapse
und @noinline
) zu vermeiden.
Verwenden Sie entweder nur DOT-Access ( object.property
) oder verwenden Sie nur dynamischen Zugriff (z. B. object[propertyName]
oder Object.keys(object)
), um auf die Eigenschaften eines bestimmten Objekttyps zuzugreifen.
Durch das Mischen dieser Verbergen einige Verwendungen einer Eigenschaft aus dem Compiler, was zu einem kaputten Ausgangscode führt, wenn die Eigenschaft umgebaut wird.
Im Allgemeinen erwartet der Compiler, eine gesamte Anwendung als einzelne Zusammenstellung anzusehen. Schnittstellen müssen sorgfältig und explizit konstruiert werden, um die Interoperation mit Code außerhalb der Kompilierungseinheit zu ermöglichen.
Der Compiler geht davon aus, dass alle Verwendungen aller Variablen und Eigenschaften angezeigt werden können und sie frei umbenennen oder entfernen, wenn sie nicht verwendet werden.
Verwenden Sie Externs -Dateien, um den Compiler über Variablen oder Eigenschaften zu informieren, die es nicht entfernen oder umbenennen darf.
Es gibt standardmäßige Externs -Dateien, die die Standard -APIs JS und DOM -Global deklarieren. Weitere Externs -Dateien sind erforderlich, wenn Sie weniger gemeinsame APIs verwenden oder erwarten, dass ein externer JavaScript -Code auf eine API in dem von Ihnen zusammengestellten Code zugreift.
Der einfachste Weg, den Compiler zu installieren, ist mit NPM oder Garn:
yarn global add google-closure-compiler
# OR
npm i -g google-closure-compiler
Der Paketmanager verknüpft die Binärdehnung für Sie und Sie können auf den Compiler zugreifen mit:
google-closure-compiler
Dies startet den Compiler im interaktiven Modus. Typ:
var x = 17 + 25 ;
Drücken Enter
, dann Ctrl+Z
(unter Windows) oder Ctrl+D
(auf Mac/Linux) und dann erneut Enter
. Der Compiler antwortet mit der kompilierten Ausgabe (standardmäßig unter Verwendung SIMPLE
Modus):
var x = 42 ;
Eine vorkompilierte Freisetzung des Compiler ist ebenfalls über Maven erhältlich.
Der Verschlusskompiler verfügt über viele Optionen zum Lesen von Eingaben aus einer Datei, zum Schreiben von Ausgaben in eine Datei, Überprüfung Ihres Codes und Ausführen von Optimierungen. Hier ist ein einfaches Beispiel für die Komprimierung eines JS -Programms:
google-closure-compiler --js file.js --js_output_file file.out.js
Wir haben den größten Nutzen vom Compiler, wenn wir ihm allen unseren Quellcode (siehe Kompilieren mehrerer Skripte), mit der wir ADVANCED
Optimierungen verwenden können:
google-closure-compiler -O ADVANCED rollup.js --js_output_file rollup.min.js
Hinweis: Die folgende Ausgabe ist nur ein Beispiel und nicht auf dem neuesten Stand. Die Wiki -Seite von Flags und Optionen wird während jeder Version aktualisiert.
Tippen Sie auf, um alle Optionen des Compiler zu sehen:
google-closure-compiler --help
--flag | Beschreibung |
---|---|
--compilation_level (-O) | Gibt die zu verwendende Kompilierungsstufe an. Optionen: BUNDLE , WHITESPACE_ONLY , SIMPLE (Standard), ADVANCED |
--env | Bestimmt den Satz von integrierten Externs. Optionen: BROWSER , CUSTOM . Standardeinstellungen zum BROWSER . |
--externs | Die Datei mit JavaScript -Externs. Sie können mehrere angeben |
--js | Der JavaScript -Dateiname. Sie können mehrere angeben. Der Flag -Name ist optional, da Args standardmäßig als Dateien interpretiert werden. Sie können auch Glob-Muster im Minimatch-Stil verwenden. Zum Beispiel verwenden Sie --js='**.js' --js='!**_test.js' _test.js alle JS -Dateien rekursiv einzuschließen |
--js_output_file | Primärausgabe Dateiname. Wenn nicht angegeben, wird die Ausgabe in STDOut geschrieben. |
--language_in | Legt die Sprachspezifikation fest, an die Eingabemöder entsprechen sollten. Optionen: ECMASCRIPT3 , ECMASCRIPT5 , ECMASCRIPT5_STRICT , ECMASCRIPT_2015 , ECMASCRIPT_2016 , ECMASCRIPT_2017 , ECMASCRIPT_2018 , ECMASCRIPT_2019 , STABLE , ECMASCRIPT_NEXT |
--language_out | Legt die Sprachspezifikation fest, an die die Ausgabe entspricht. Optionen: ECMASCRIPT3 , ECMASCRIPT5 , ECMASCRIPT5_STRICT , ECMASCRIPT_2015 , ECMASCRIPT_2016 , ECMASCRIPT_2017 , ECMASCRIPT_2018 , ECMASCRIPT_2019 , STABLE |
--warning_level (-W) | Gibt die zu verwendende Warnstufe an. Optionen: QUIET , DEFAULT , VERBOSE |
Sie können in einem JS-Programm auf den Compiler zugreifen, indem Sie google-closure-compiler
importieren:
import closureCompiler from 'google-closure-compiler' ;
const { compiler } = closureCompiler ;
new compiler ( {
js : 'file-one.js' ,
compilation_level : 'ADVANCED'
} ) ;
Dieses Paket bietet in den meisten Fällen den programmatischen Zugriff auf die native Graal -Binärdatei und fällt ansonsten auf die Java -Version zurück.
Wenn Sie mehrere Skripte haben, sollten Sie sie alle zusammen mit einem Kompilierungsbefehl kompilieren.
google-closure-compiler in1.js in2.js in3.js --js_output_file out.js
Sie können auch Globs im Minimatch-Stil verwenden.
# 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
Der Verschluss Compiler verkettet die Dateien in der Reihenfolge, die sie an der Befehlszeile übergeben haben.
Wenn Sie GLIPS oder viele Dateien verwenden, können Sie Probleme mit der Verwaltung von Abhängigkeiten zwischen Skripten begegnen. In diesem Fall sollten Sie die mitgelieferten lib/base.js verwenden, die Funktionen zur Durchsetzung von Abhängigkeiten zwischen Skripten (nämlich goog.module
und goog.require
) bereitstellen. Der Verschlusskompiler ordnet die Eingänge automatisch nach.
Der Verschluss Compiler veröffentlicht mit lib/base.js, die JavaScript -Funktionen und Variablen liefert, die als Primitive dienen, die bestimmte Merkmale des Verschlussescompilers ermöglichen. Diese Datei ist ein Derivat der identisch benannten Base.js in der bald veralteten Verschlussbibliothek. Diese base.js
wird durch den Closeure Compiler für die Zukunft unterstützt und kann neue Funktionen erhalten. Es wurde entwickelt, um seine wahrgenommenen Kernteile nur beizubehalten.
Um den Compiler selbst aufzubauen, benötigen Sie Folgendes:
Voraussetzung | Beschreibung |
---|---|
Java 11 oder später | Wird verwendet, um den Quellcode des Compilers zu kompilieren. |
Nodejs | Wird verwendet, um Ressourcen zu generieren, die von Java Compilation verwendet werden |
Git | Wird von Bazel verwendet, um Abhängigkeiten herunterzuladen. |
Baselisk | Wird verwendet, um die verschiedenen Compiler -Ziele zu erstellen. |
Bazelisk ist ein Wrapper um Basel, der die entsprechende Version von Bazel für ein bestimmtes Repository dynamisch lädt. Die Verwendung verhindert falsche Fehler, die sich aus der Verwendung der falschen Version von Bazel zum Aufbau des Compilers ergeben, und es wird die Verwendung verschiedener Baselversionen für andere Projekte einfach ermöglichen.
Bazelisk ist über viele Paketmanager erhältlich. Fühlen Sie sich frei, das zu verwenden, mit dem Sie am wohlsten sind.
Anweisungen zur Installation von Baselisk.
$ bazelisk build //:compiler_uberjar_deploy.jar
# OR to build everything
$ bazelisk build //:all
Tests können auf ähnliche Weise durchgeführt werden. Im folgenden Befehl werden alle Tests im Repo ausgeführt.
$ bazelisk test //:all
Es gibt Hunderte von individuellen Testzielen, daher dauert es einige Minuten, um alle zu betreiben. Während der Entwicklung ist es normalerweise besser, die genauen Tests anzugeben, an denen Sie interessiert sind.
bazelisk test //: $path_to_test_file
Siehe Bazel IDE -Integrationen.
Sobald der Compiler gebaut wurde, befindet sich das zusammengestellte Glas im bazel-bin/
Verzeichnis. Sie können mit einem Anruf bei java -jar ...
oder mit dem Skript package.json zugreifen:
# java -jar bazel-bin/compiler_uberjar_deploy.jar [...args]
yarn compile [...args]
src/com/google/javascript/jscomp/CommandLineRunner.java
oder erstellen Sie eine eigene erweiterte Version der Klasse.Wenn Sie sich jedoch für einen Beitrag entscheiden, halten Sie sich bitte an unseren Verhaltenskodex, um unsere Community zu einem gesunden und einladenden Ort zu halten.
Copyright 2009 Die Verschluss -Compiler -Autoren.
Lizenziert unter der Apache -Lizenz, Version 2.0 (der "Lizenz"); Sie dürfen diese Datei nur in Übereinstimmung mit der Lizenz verwenden. Sie können eine Kopie der Lizenz unter http://www.apache.org/licenses/license-2.0 erhalten.
Sofern nicht nach geltendem Recht oder schriftlich zu vereinbart wird, wird die im Rahmen der Lizenz verteilte Software auf "As is" -Basis ohne Gewährleistung oder Bedingungen jeglicher Art ausdrücklich oder impliziert verteilt. Siehe die Lizenz für die spezifischen Sprachberechtigungen und Einschränkungen im Rahmen der Lizenz.
Codepfad | src/com/google/javascript/rhino , test/com/google/javascript/rhino |
URL | https://developer.mozilla.org/en-us/docs/mozilla/projects/rhino |
Version | 1,5R3 mit starken Modifikationen |
Lizenz | Netscape Public Lizenz und MPL / GPL Dual Lizenz |
Beschreibung | Eine Teilkopie von Mozilla Rhino. Mozilla Rhino ist eine Implementierung von JavaScript für die JVM. Die JavaScript -Parse -Baumdatenstrukturen wurden extrahiert und für den JavaScript -Compiler von Google erheblich geändert. |
Lokale Modifikationen | Die Pakete wurden umbenannt. Der für den Parse Tree nicht relevante Code wurde entfernt. Ein JSDOC -Parser und ein statisches Schreibsystem wurden hinzugefügt. |
URL | http://args4j.kohsuke.org/ |
Version | 2.33 |
Lizenz | MIT |
Beschreibung | Args4J ist eine kleine Bibliothek der Java -Klasse, mit der die Optionen/Argumente/Argumente für die Befehlszeilen in Ihrer CUI -Anwendung einfach analysiert werden können. |
Lokale Modifikationen | Keiner |
URL | https://github.com/google/guava |
Version | 31.0.1 |
Lizenz | Apache -Lizenz 2.0 |
Beschreibung | Googles Kern -Java -Bibliotheken von Google. |
Lokale Modifikationen | Keiner |
URL | https://github.com/findbugsproject/findbugs |
Version | 3.0.1 |
Lizenz | BSD -Lizenz |
Beschreibung | Anmerkungen zur Erkennung von Softwaredefekten. |
Lokale Modifikationen | Keiner |
URL | http://junit.org/junit4/ |
Version | 4.13 |
Lizenz | Gemeinsame öffentliche Lizenz 1.0 |
Beschreibung | Ein Framework zum Schreiben und Ausführen von automatisierten Tests in Java. |
Lokale Modifikationen | Keiner |
URL | https://github.com/google/protobuf |
Version | 3.0.2 |
Lizenz | Neue BSD -Lizenz |
Beschreibung | Unterstützende Bibliotheken für Protokollpuffer, eine Codierung strukturierter Daten. |
Lokale Modifikationen | Keiner |
URL | https://github.com/google/re2j |
Version | 1.3 |
Lizenz | Neue BSD -Lizenz |
Beschreibung | Lineare Zeit reguläre Ausdrucks Matching in Java. |
Lokale Modifikationen | Keiner |
URL | https://github.com/google/truth |
Version | 1.1 |
Lizenz | Apache -Lizenz 2.0 |
Beschreibung | Assertion/Proposition -Framework für Java -Unit -Tests |
Lokale Modifikationen | Keiner |
URL | https://ant.apache.org/bindownload.cgi |
Version | 1.10.11 |
Lizenz | Apache -Lizenz 2.0 |
Beschreibung | Ant ist ein Java -basierter Build -Tool. Theoretisch ist es wie "make" ohne Make's Falten und mit der vollen Tragbarkeit des reinen Java -Code. |
Lokale Modifikationen | Keiner |
URL | https://github.com/google/gson |
Version | 2.9.1 |
Lizenz | Apache -Lizenz 2.0 |
Beschreibung | Eine Java-Bibliothek, um JSON in Java-Objekte und umgekehrt umzuwandeln |
Lokale Modifikationen | Keiner |
Codepfad | contrib/nodejs |
URL | https://github.com/dcodeeio/node.jsclososous-compiler-externs |
Version | E891B4FBCF5F466CC4307B0FA842A7D8163A073A |
Lizenz | Apache 2.0 Lizenz |
Beschreibung | Geben Sie Verträge für NodeJS -APIs ein |
Lokale Modifikationen | Wesentliche Änderungen, um sie mit NPMCommandLinerununner kompatibel zu machen. |