Existe uma maneira de dizer ao Google Closure Compiler para * NÃO * incorporar minhas funções locais?

Aqui está o que estou procurando:

Quero usar os maravilhosos recursos da minificação do modo SIMPLE enquanto desativa apenas um recurso específico (desabilite a função local em linha).


ATUALIZAÇÃO: A resposta é NÃO, não é possível, dada a minha configuração. Mas, para mim, há uma solução alternativa, pois estou usando Grails.Como o @Chad explicou abaixo, "Isso viola as principais premissas do compilador". Veja meu UPDATE3 abaixo para obter mais informações.


EM FORMULÁRIO DE PERGUNTA:

estou a usarCompilationLevel.SIMPLE_OPTIMIZATIONS que faz tudo o que eu quero, exceto que está incorporando minhas funções locais.Existe alguma maneira de contornar isso? Por exemplo, há uma configuração que posso colocar nos meus arquivos JS para informar ao Google Closure para não incorporar minhas funções locais?

Seria legal ter algumas diretivas na parte superior do meu arquivo javascript, como:

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

Estou desenvolvendo um aplicativo Grails e usando oGrails-pipeline de ativos plug-in, que usa o Google Closure Compiler (doravante, Compiler). O plugin suporta os diferentes níveis de minificação que o Compiler suporta através da configuração do Grailsgrails.assets.minifyOptions. Isso permite 'SIMPLES', 'AVANÇADO', 'WHITESPACE_ONLY'.

Chamadas AssetCompiler.groovy (plugin de pipeline de ativos)ClosureCompilerProcessor.process()

Isso acaba atribuindoSIMPLE_OPTIMIZATIONS no objeto CompilerOptions. E ao fazer isso,CompilerOptions.inlineLocalFunctions = true como um subproduto (esse é um comportamento codificado no Compiler). Se eu fosse usarWHITESPACE_ONLY o resultado seriainlineLocalFunctions=false.

Portanto, usando a configuração 'SIMPLE' do Asset Pipeline, as funções locais estão sendo incorporadas e isso está me causando problemas. Exemplo: ExtJSext-all-debug.js que usa muitas funções locais.

SO postÉ possível fazer o compilador do Google Closure * não * incorporar determinadas funções? fornece alguma ajuda. Eu posso usar o seuwindow['dontBlowMeAway'] = dontBlowMeAway truque para manter minhas funções inlining. No entanto, tenho MUITAS funções e não pretendo fazer isso manualmente para cada uma; nem gostaria de escrever um script para fazer isso por mim. Criar um modelo JS e tentar identificar funções locais não parece seguro, divertido nem rápido.

A postagem anterior do SO direciona o leitor parahttps://developers.google.com/closure/compiler/docs/api-tutorial3#removal, onde owindow['bla'] O truque é explicado e funciona.

Uau, obrigado por ler tanto tempo.

Socorro? :-)

UPDATE1:

OK. Ao dedicar todo o esforço para escrever essa pergunta, posso ter um truque que pode funcionar. Grails usa Groovy. O Groovy facilita a interceptação de chamada de método usando sua API MetaClass.

Vou tentar interceptar a chamada para:

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

Meu método de interceptação será parecido com:

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

É hora de dormir, então terei que tentar isso mais tarde. Mesmo assim, seria bom resolver isso sem hackear.


UPDATE2: A resposta em uma postagem semelhante (É possível fazer o compilador do Google Closure * não * incorporar determinadas funções?) não resolve o meu problema devido à grande quantidade de funções que preciso inline. Eu já expliquei esse ponto.

Tome o arquivo ExtJS que citei acima como um exemplo de por que os itens acimapost SO semelhante não resolve o meu problema. Veja o código bruto paraext-all-debug.js. Encontre a função byAttribute (). Continue procurando a string "byAttribute" e verá que ela faz parte das strings que estão sendo definidas. Não conheço esse código, mas suponho que esses valores baseados em string debyAttribute são passados posteriormente paraAvaliação de JS () função para execução. O compilador não altera esses valores debyAttribute quando faz parte de uma string. Uma vezfunction byAttribute está embutido, as tentativas de chamar a função não são mais possíveis.


UPDATE3: Tentei duas estratégias para resolver esse problema e ambas foram infrutíferas. No entanto, implementei com sucesso uma solução alternativa. Minhas tentativas fracassadas:

Use a interceptação do método Groovy (Meta Object Protocol, também conhecido como MOP) para interceptarcom.google.javascript.jscomp.Compiler.compile().Bifurque o encerramento-compiler.jar (faça minha própria cópia personalizada) e modifiquecom.google.javascript.jscomp.applySafeCompilationOptions() pela configuraçãooptions.setInlineFunctions(Reach.NONE); em vez de LOCAL.

A interceptação de método não funciona porqueCompiler.compile() é uma classe Java que é chamada por uma classe Groovy marcada como@CompileStatic. Isso significa que o MOP do Groovy não é usado quandoprocess() liga para o GoogleCompiler.compile(). AtéClosureCompilerProcessor.translateMinifyOptions() (Código Groovy) não pode ser interceptado porque a classe é@CompileStatic. O único método que pode ser interceptado éClosureCompilerProcessor.process().

Forçar o fechamento do compiler.jar do Google foi meu último recurso feio. Mas, como o @Chad disse abaixo, basta inseriroptions.setInlineFunctions(Reach.NONE) no lugar certo não ressuscitou meus nomes de funções JS embutidos. Tentei alternar outras opções, comosetRemoveDeadCode=false para nenhum proveito. Eu percebi o que Chad disse que estava certo. Eu acabaria alterando as configurações e provavelmente destruindo o funcionamento da minificação.

Minha solução: Compilei previamente o ext-all-debug.js com o UglifyJS e os adicionei ao meu projeto. Eu poderia ter nomeado os arquivosext-all-debug.min.js para fazê-lo de forma mais limpa, mas não o fiz. Abaixo estão as configurações que coloquei no meu 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'
]

Feito. Problema resolvido.




Palavras-chave: minify, minification, uglify, UglifyJS, UglifyJS2

questionAnswers(2)

yourAnswerToTheQuestion