Ist es eine Möglichkeit, Google Closure Compiler anzuweisen, meine lokalen Funktionen * NICHT * einzubinden?

Hier ist was ich suche:

Ich möchte die wunderbaren Funktionen der SIMPLE-Modus-Minimierung nutzen und gleichzeitig nur eine bestimmte Funktion deaktivieren (lokale Funktion inline deaktivieren).


UPDATE: Die Antwort ist NEIN, es ist bei meinem Setup nicht möglich. Aber für mich gibt es eine Problemumgehung, wenn ich Grails verwende. Wie @Chad weiter unten erklärt hat, "verletzt dies die Kernannahmen des Compilers". Weitere Informationen finden Sie in meinem UPDATE3 unten.


IN FRAGEFORMULAR:

Ich benutzeCompilationLevel.SIMPLE_OPTIMIZATIONS was macht alles was ich will, außer dass es meine lokalen Funktionen inliniert.Ist da ein Weg dran vorbei? Gibt es beispielsweise eine Einstellung, die ich in meine JS-Dateien einfügen kann, um Google Closure anzuweisen, meine lokalen Funktionen nicht zu integrieren?

Es wäre cool, wenn oben in meiner Javascript-Datei einige Anweisungen stehen würden, z. B .:

// This is a JS comment...
// google.closure.compiler = [inlineLocalFunctions: false]

Ich entwickle eine Grails-App und benutze dasGrails Asset-Pipeline Plugin, das den Google Closure Compiler (im Folgenden: Compiler) verwendet. Das Plugin unterstützt die verschiedenen Verkleinerungsstufen, die der Compiler über die Grails config @ unterstütz grails.assets.minifyOptions. Dies ermöglicht 'SIMPLE', 'ADVANCED', 'WHITESPACE_ONLY'.

AssetCompiler.groovy (Asset-Pipeline-Plugin) ruft @ aClosureCompilerProcessor.process()

Das weist schließlichSIMPLE_OPTIMIZATIONS für das CompilerOptions-Objekt. Und auf diese WeiseCompilerOptions.inlineLocalFunctions = true als Nebenprodukt (dies ist ein hartcodiertes Verhalten im Compiler). Wenn ich @ benutzen würWHITESPACE_ONLY das Ergebnis wäreinlineLocalFunctions=false.

Wenn Sie also die 'SIMPLE'-Einstellung von Asset Pipeline verwenden, werden lokale Funktionen eingebunden, was mir Probleme bereitet. Beispiel: ExtJS ext-all-debug.js verwendet viele lokale Funktionen.

SO postIst es möglich, den Google Closure-Compiler * nicht * in bestimmte Funktionen einzubinden? bietet Hilfe. Ich kann sein @ verwendwindow['dontBlowMeAway'] = dontBlowMeAway Trick, um meine Funktionen vom Inlining abzuhalten. Ich habe jedoch VIELE Funktionen und werde dies nicht für jede einzeln manuell ausführen. noch würde ich ein Skript schreiben wollen, um es für mich zu tun. Das Erstellen eines JS-Modells und der Versuch, lokale Funktionen zu identifizieren, klingt weder sicher noch unterhaltsam noch schnell.

Der vorherige SO-Beitrag verweist den Leser aufhttps: //developers.google.com/closure/compiler/docs/api-tutorial3#remova, bei dem diewindow['bla'] Trick wird erklärt, und es funktioniert.

Wow, danke, dass du so lange gelesen hast.

Hilfe? : -)

UPDATE1:

Okay. Während ich mir die Mühe mache, diese Frage zu schreiben, habe ich vielleicht einen Trick, der funktionieren könnte. Grails benutzt Groovy. Groovy vereinfacht das Abfangen von Methodenaufrufen mithilfe der MetaClass-API.

Ich werde versuchen, den Anruf abzufangen, um:

com.google.javascript.jscomp.Compiler.compile(
    List<T1> externs, List<T2> inputs, CompilerOptions options)

Meine Abfangmethode sieht folgendermaßen aus:

options.inlineLocalFunctions=false
// Then delegate call to the real compile() method

Es ist Schlafenszeit, also muss ich das später versuchen. Trotzdem wäre es schön, dies ohne einen Hack zu lösen.


UPDATE2: Die Antwort in einem ähnlichen Beitrag Ist es möglich, den Google Closure-Compiler * nicht * in bestimmte Funktionen einzubinden?) löst mein Problem nicht, da ich eine große Anzahl von Funktionen benötige. Ich habe diesen Punkt bereits erklärt.

Nehmen Sie die ExtJS-Datei, die ich oben als Beispiel für die oben genanntensimilar SO post löst mein Problem nicht. Schauen Sie sich den Rohcode für @ a ext-all-debug.js. Suchen Sie die Funktion byAttribute (). Suchen Sie dann weiter nach der Zeichenfolge "byAttribute" und Sie werden sehen, dass sie Teil der Zeichenfolgen ist, die definiert werden. Ich bin mit diesem Code nicht vertraut, nehme aber an, dass diese auf Zeichenfolgen basierenden Werte vonbyAttribute werden später an @ übergeb JS's eval () Funktion zur Ausführung. Der Compiler ändert diese Werte von @ nicbyAttribute wenn es Teil eines Strings ist. Einmalfunction byAttribute ist eingeblendet, Versuche, die Funktion aufzurufen, sind nicht mehr möglich.


UPDATE3: Ich habe zwei Strategien versucht, um dieses Problem zu lösen, und beide waren erfolglos. Ich habe jedoch eine Problemumgehung erfolgreich implementiert. Meine fehlgeschlagenen Versuche:

Verwenden Sie das Abfangen von Groovy-Methoden (Meta Object Protocol, auch bekannt als MOP), um @ abzufangecom.google.javascript.jscomp.Compiler.compile().Fork the closure-compiler.jar (mache meine eigene Kopie) und änderecom.google.javascript.jscomp.applySafeCompilationOptions() indem man es einstelltoptions.setInlineFunctions(Reach.NONE); anstelle von LOCAL.

Method Interception funktioniert nicht, weilCompiler.compile() ist eine Java-Klasse, die von einer Groovy-Klasse aufgerufen wird, die als @ markiert is@CompileStatic. Das bedeutet, dass Groovys MOP nicht verwendet wird, wennprocess() ruft das @ von Google aCompiler.compile(). SogarClosureCompilerProcessor.translateMinifyOptions() (Groovy Code) kann nicht abgefangen werden, da die Klasse @ i@CompileStatic. Die einzige Methode, die abgefangen werden kann, istClosureCompilerProcessor.process().

Forking Googles Closure-Compiler.jar war mein letzter hässlicher Ausweg. Aber genau wie @Chad unten sagte, einfach @ einfügoptions.setInlineFunctions(Reach.NONE) am richtigen Ort hat meine Inline-JS-Funktionsnamen nicht wiederbelebt. Ich habe versucht, andere Optionen wie @ umzuschaltesetRemoveDeadCode=false umsonst. Ich erkannte, was Chad sagte, war richtig. Am Ende würde ich die Einstellungen umdrehen und wahrscheinlich zerstören, wie die Verkleinerung funktioniert.

Meine Lösung Ich habe ext-all-debug.js mit UglifyJS vorkomprimiert und meinem Projekt hinzugefügt. Ich hätte die Dateien @ benennen könnext-all-debug.min.js um es sauberer zu machen, aber ich habe es nicht getan. Im Folgenden sind die Einstellungen aufgeführt, die ich in Grails Config.groovy vorgenommen habe:

grails.assets.minifyOptions = [
    optimizationLevel: 'SIMPLE' // WHITESPACE_ONLY, SIMPLE or ADVANCED
]

grails.assets.minifyOptions.excludes = [
    '**ext-all-debug.js',
    '**ext-theme-neptune.js'
]

Erledigt. Problem gelöst




Keywords: minify, minification, uglify, UglifyJS, UglifyJS2

Antworten auf die Frage(4)

Ihre Antwort auf die Frage