¿Hay alguna manera de decirle a Google Closure Compiler que * NO * incorpore mis funciones locales?

Esto es lo que estoy buscando:

Quiero usar las maravillosas funciones de la minificación en modo SIMPLE mientras deshabilito solo una función específica (deshabilitar la función local en línea).


ACTUALIZACIÓN: La respuesta es NO, no es posible dada mi configuración. Pero para mí hay una solución, dado que estoy usando Grails.Como @Chad ha explicado a continuación, "Esto viola los supuestos básicos del compilador". Vea mi ACTUALIZACIÓN3 a continuación para obtener más información.


EN FORMA DE PREGUNTA:

Estoy usandoCompilationLevel.SIMPLE_OPTIMIZATIONS que hace todo lo que quiero, excepto que incluye mis funciones locales.¿Hay alguna forma de evitar esto? Por ejemplo, ¿hay una configuración que pueda colocar en mis archivos JS para decirle a Google Closure que no incorpore mis funciones locales?

Sería genial tener algunas directivas en la parte superior de mi archivo javascript como:

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

Estoy desarrollando una aplicación Grails y usando elCartera de activos de Grails plugin, que utiliza el Compilador de cierre de Google (en adelante, Compilador). El complemento admite los diferentes niveles de minificación que el compilador admite a través de la configuración de Grailsgrails.assets.minifyOptions. Esto permite 'SIMPLE', 'AVANZADO', 'WHITESPACE_ONLY'.

Llamadas AssetCompiler.groovy (plugin de pipeline de activos)ClosureCompilerProcessor.process()

Eso eventualmente asignaSIMPLE_OPTIMIZATIONS en el objeto CompilerOptions. Y al hacerlo,CompilerOptions.inlineLocalFunctions = true como subproducto (este es un comportamiento codificado en el compilador). Si tuviera que usarWHITESPACE_ONLY el resultado seríainlineLocalFunctions=false.

Entonces, al usar la configuración 'SIMPLE' de Asset Pipeline, las funciones locales se están alineando y eso me está causando problemas. Ejemplo: ExtJSext-all-debug.js que usa muchas funciones locales.

Publicar SO¿Es posible hacer que el compilador de Google Closure * no * incorpore ciertas funciones? proporciona algo de ayuda Puedo usar suwindow['dontBlowMeAway'] = dontBlowMeAway truco para evitar que mis funciones se alineen. Sin embargo, tengo MUCHAS funciones y no estoy dispuesto a hacer esto manualmente para cada una; ni me gustaría escribir un guión para hacerlo por mí. Crear un modelo JS e intentar identificar funciones locales no parece seguro, divertido ni rápido.

La publicación SO anterior dirige al lector ahttps://developers.google.com/closure/compiler/docs/api-tutorial3#removal, donde elwindow['bla'] El truco se explica y funciona.

Guau, gracias por leer tanto tiempo.

¿Ayuda? :-)

ACTUALIZACIÓN1:

Bueno. Mientras gasto todo el esfuerzo en escribir esta pregunta, puedo tener un truco que podría funcionar. Grails usa Groovy. Groovy facilita la intercepción de llamadas de método utilizando su API MetaClass.

Voy a intentar interceptar la llamada a:

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

Mi método de intercepción se verá así:

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

Es hora de dormir, así que tendré que probar esto más tarde. Aun así, sería bueno resolver esto sin un truco.


ACTUALIZACIÓN2:&nbsp;La respuesta en una publicación similar (¿Es posible hacer que el compilador de Google Closure * no * incorpore ciertas funciones?) no resuelve mi problema debido a la gran cantidad de funciones que necesito en línea. Ya he explicado este punto.

Tome el archivo ExtJS que cité anteriormente como un ejemplo de por qué lo anteriorpublicación SO similar&nbsp;no resuelve mi problema Mira el código en bruto paraext-all-debug.js. Encuentra la función byAttribute (). Luego siga buscando la cadena "byAttribute" y verá que es parte de las cadenas que se están definiendo. No estoy familiarizado con este código, pero supongo que estos valores basados en cadenas debyAttribute&nbsp;luego se pasan aEval de JS ()&nbsp;Función para la ejecución. El compilador no altera estos valores debyAttribute&nbsp;cuando es parte de una cadena. Una vezfunction byAttribute&nbsp;está en línea, ya no es posible llamar a la función.


ACTUALIZACIÓN3:&nbsp;Intenté dos estrategias para resolver este problema y ambas resultaron infructuosas. Sin embargo, implementé con éxito una solución alternativa. Mis intentos fallidos:

Use el método de intercepción Groovy (Meta Object Protocol, también conocido como MOP) para interceptarcom.google.javascript.jscomp.Compiler.compile().Bifurque el cierre-compiler.jar (haga mi propia copia personalizada) y modifiquecom.google.javascript.jscomp.applySafeCompilationOptions()&nbsp;configurandooptions.setInlineFunctions(Reach.NONE);&nbsp;en lugar de LOCAL.

La intercepción de métodos no funciona porqueCompiler.compile()&nbsp;es una clase Java que es invocada por una clase Groovy marcada como@CompileStatic. Eso significa que el MOP de Groovy no se usa cuandoprocess()&nbsp;llama a GoogleCompiler.compile(). InclusoClosureCompilerProcessor.translateMinifyOptions()&nbsp;(Código maravilloso) no se puede interceptar porque la clase es@CompileStatic. El único método que puede ser interceptado esClosureCompilerProcessor.process().

Bifurcar el cierre-compiler.jar de Google fue mi último recurso feo. Pero al igual que @Chad dijo a continuación, simplemente insertandooptions.setInlineFunctions(Reach.NONE)&nbsp;en el lugar correcto no resucitó mis nombres de funciones JS en línea. Traté de alternar otras opciones comosetRemoveDeadCode=false&nbsp;en vano. Me di cuenta de que Chad dijo que era correcto. Terminaría cambiando la configuración y probablemente destruyendo cómo funciona la minificación.

Mi solución:&nbsp;Precomprimí ext-all-debug.js con UglifyJS y los agregué a mi proyecto. Podría haber nombrado los archivosext-all-debug.min.js&nbsp;para hacerlo más limpiamente pero no lo hice. A continuación se encuentran las configuraciones que coloqué en mi Grails Config.groovy:

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

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

Hecho. Problema resuelto.




Palabras clave: minify, minification, uglify, UglifyJS, UglifyJS2