Entfernen von Debug-Code aus einer Funktion mithilfe der einfachen Closure Compiler-Optimierungen

8

Ich suche nach einer Möglichkeit, Debug-Code von Funktionen zu entfernen, damit ich Test-Hooks zu Schließungen hinzufügen kann. Ich habe gelesen Google Closure Compiler erweitert: Entferne Codeblöcke zur Kompilierzeit und getestet Debug-Code mit dem folgenden zu entfernen:

%Vor%

Einfache Optimierung mit --define='DEBUG=false' reduziert dies auf var DEBUG=!1; . Gleiches gilt für das:

%Vor%

Wo ich Probleme habe, verwende ich diese Konvention in einer Funktion:

%Vor%

Dies reduziert sich auf Folgendes:

%Vor%

Ich würde erwarten, dass es sich weiter reduziert auf:

%Vor%

Gibt es einen Grund, warum dies nicht wie erwartet funktioniert? Ich suche wirklich nur nach einer sauberen Möglichkeit, Debug-Code zu entfernen und bin nicht bereit, in fortgeschrittene Optimierungen einzutauchen.

Aktualisieren

Per @ Johns Antwort, ich habe meinen eigenen Compiler implementiert und festgestellt, dass die folgende Konfiguration if (DEBUG) {} innerhalb und außerhalb des Codes für den Fall von @define entfernt:

%Vor%

Dies funktioniert gut genug für eine einzelne Datei mit den folgenden Einschränkungen:

  1. Dies erfordert, dass var DEBUG in jeder Datei definiert wird, was eine schlechte Übung ist.
  2. Wenn Sie mehrere Dateien kombinieren, können Sie nur eine einzige var DEBUG haben oder der Compiler kann nicht in der Umgebung optimieren. Dies könnte vermieden werden, indem jede Datei einzeln kompiliert und zusammengeführt wird.
  3. Da der Wert am Anfang der Datei definiert ist, gibt es keine Flexibilität, den Wert zuvor zu erhalten.

Ich habe mit der Idee gespielt, alle var DEBUG -Definitionen aus den Dateien zu entfernen und sie vor der Ausführung in die Quelle oder in das externe Verzeichnis zu schreiben, aber ich habe zwei Probleme festgestellt:

  • Die Definition in extern scheint nichts zu tun.
  • Undefiniert DEBUG im nicht kompilierten Code löst einen Referenzfehler im Browser aus.

Die ideale Option wäre, window.DEBUG zu testen, was keinen Referenzfehler verursacht. Wenn% ce_de% auf der obersten Ebene injiziert wird und dabei /** @const */ var window = {}; /** @const */ window.DEBUG = false; reduziert wird, wird die Optimierung tatsächlich zurückgesetzt, wenn sie in einer Funktion platziert wird.

Wenn keine andere Compiler-Option funktioniert, ist die einzige Option, die wirklich Sinn macht, die Verwendung von if (window.DEBUG) {} und vor der Kompilierung inject window.DEBUG und die globale Ersetzung von /** @const */ var DEBUG = false; mit /\bwindow.DEBUG\b/ . Gibt es einen besseren Weg?

    
Brian Nickel 09.07.2012, 20:01
quelle

6 Antworten

3

Mit einem benutzerdefinierten Build des Compilers können Sie dies tun. Sie wollen grundsätzlich "konstante Variablen":

options.setInlineConstantVars (true);

Sie können es hier in applySafeCompilationOptions hinzufügen: Ссылка

Oder Sie können die Java-API verwenden und die Option hinzufügen (ohne den Code des Compilers zu ändern). Michael Bolin hat ein Beispiel gegeben, wie man das hier macht:

Ссылка

    
John 09.07.2012 23:33
quelle
3

Verwenden Sie @define Annotation:

%Vor%

DEBUG = true;

Und kompiliere mit Option

- define="DEBUG = false"

    
user2712511 27.01.2014 10:58
quelle
2

Das ist eine alte Antwort, aber ich habe einen Weg gefunden, der hier nicht erwähnt wird.

%Vor%

Mit ADVANCED_OPTIMIZATIONS kompiliert dies zu diesem:

%Vor%

In unserem Build-Skript können wir die DEBUG-Zeile neu schreiben, um sie auf false zu setzen, was dann zu dieser Ausgabe führen würde.

%Vor%

Der Grund dafür ist, dass Closure nicht erreichbaren Code entfernt. Durch das Erstellen der Closure und das Definieren einer lokalen Variablen kann Closure sehen, dass wir etwas wie window.DEBUG === true nicht tun können, so dass der Code niemals ausgeführt wird.

    
FakeRainBrigand 30.08.2013 11:18
quelle
1

Ihre DEBUG Variable ist derzeit global. GCC wird globale Variablen im einfachen Optimierungsmodus nicht entfernen oder umbenennen, sodass sie für Code in anderen Skripts verfügbar bleiben, die möglicherweise darauf zugreifen möchten. Versuchen Sie, Ihren Code in eine anonyme Funktion einzufügen.

    
Oleg V. Volkov 09.07.2012 22:59
quelle
1

Die Art und Weise, wie ich das Problem gelöst habe, "Debug-Funktionen von geschlossenem kompiliertem Javascript mit SIMPLE_OPTIMIZATION zu entfernen", war die Kombination einer ähnlichen Methode, wie sie @John vorschlägt, sowie die Verwendung einiger @Brian Nichols-Updates. Ich konnte den Compiler nur dazu bringen, die Zeilen zu entfernen, indem ich den globalen Bereich meiner Haupt-js-Datei platzierte und eine benutzerdefinierte Kompilierung durchführte (mit mehreren .js-Dateien, die diese trotzdem entfernten)

%Vor%

und dann Kompilieren des Closure-Compilers Java mit ant, um diese Option einzufügen options.setInlineVariables (CompilerOptions.Reach.ALL);  unter der applySafeCompilationOptions-Funktion in der CompilationLevel.java-Datei, wie @John vorschlägt. Das hat für mich funktioniert und meine Codebasis nicht wie ADVANCED gebrochen ...

    
steveinatorx 12.10.2013 02:10
quelle
0

Entfernen Sie var DEBUG = true; aus Ihrem Code und konvertieren Sie alle Ihre Bedingungen, die if (DEBUG) auf if (goog.DEBUG) überprüfen. Ändern Sie Ihre Compiler-Option, um --define goog.DEBUG=false zu lesen. Die Variable goog ist in die API Closure Library integriert, um Optionen und Flags für den Compiler bereitzustellen.

    
alecananian 09.07.2012 20:45
quelle