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:
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:
Dies funktioniert gut genug für eine einzelne Datei mit den folgenden Einschränkungen:
var DEBUG
in jeder Datei definiert wird, was eine schlechte Übung ist. 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. 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:
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?
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:
Verwenden Sie @define Annotation:
%Vor%DEBUG = true;
Und kompiliere mit Option
- define="DEBUG = false"
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.
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.
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.
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 ...
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.
Tags und Links javascript google-closure-compiler minify