我在寻找什么:
问题形式:
CompilationLevel.SIMPLE_OPTIMIZATIONS
来执行我想要的一切,除了它内联了我的本地函数。 在我的javascript文件顶部设置一些指令会很酷,例如:
// This is a JS comment...
// google.closure.compiler = [inlineLocalFunctions: false]
我正在开发Grails应用程序,并使用Grails asset-pipeline插件,该插件使用Google Closure编译器(以下称为Compiler)。该插件通过Grails config grails.assets.minifyOptions支持Compiler支持的不同缩小级别。这允许“SIMPLE”,“ADVANCED”,“WHITESPACE_ONLY”。
AssetCompiler.groovy( Assets 管道插件)调用
ClosureCompilerProcessor.process()
最终,在CompilerOptions对象上分配了
SIMPLE_OPTIMIZATIONS
。通过这样做,CompilerOptions.inlineLocalFunctions = true
作为副产品(这是Compiler中的硬编码行为)。如果我使用WHITESPACE_ONLY
,结果将是inlineLocalFunctions=false
。因此,通过使用Asset Pipeline的“SIMPLE”设置,内联了本地函数,这给我带来了麻烦。示例:ExtJS ext-all-debug.js使用很多本地函数。
所以Is it possible to make Google Closure compiler *not* inline certain functions? post提供了一些帮助。我可以使用其
window['dontBlowMeAway'] = dontBlowMeAway
技巧来防止函数内联。但是我有很多功能,我不会为每个功能手动进行操作;我也不想写一个脚本来帮我做。创建JS模型并尝试标识本地函数听起来并不安全,有趣或快速。上一则SO文章将读者定向到https://developers.google.com/closure/compiler/docs/api-tutorial3#removal,在其中解释了
window['bla']
技巧,并且该方法有效。哇,谢谢您读了这么长时间。
救命? :-)
UPDATE1:
好的。在花所有的精力写这个问题的同时,我可能会有一个可行的技巧。 Grails使用Groovy。 Groovy使用其MetaClass API使方法调用拦截变得容易。
我将尝试拦截对以下内容的调用:
com.google.javascript.jscomp.Compiler.compile(
List<T1> externs, List<T2> inputs, CompilerOptions options)
我的拦截方法如下所示:
options.inlineLocalFunctions=false
// Then delegate call to the real compile() method
现在是上床时间,所以我以后必须再试一次。即便如此,解决这个问题也很不错。
UPDATE2:
由于我需要内联大量功能,因此类似帖子(Is it possible to make Google Closure compiler *not* inline certain functions?)中的响应无法解决我的问题。我已经解释了这一点。
以我上面引用的ExtJS文件为例,说明上面的similar SO post为什么不能解决我的问题。查看ext-all-debug.js的原始代码。找到byAttribute()函数。然后继续查找字符串“byAttribute”,您将看到它是正在定义的字符串的一部分。我对这段代码不熟悉,但是我想将这些基于字符串的
byAttribute
值稍后传递给JS's eval()函数以执行。作为字符串的一部分时,编译器不会更改byAttribute
的这些值。内联function byAttribute
后,将无法再尝试调用该函数。UPDATE3:我尝试了两种策略来解决此问题,但均未成功。但是,我成功实现了一种解决方法。我失败的尝试:
com.google.javascript.jscomp.Compiler.compile()
。 com.google.javascript.jscomp.applySafeCompilationOptions()
而不是LOCAL来修改options.setInlineFunctions(Reach.NONE);
。 方法拦截不起作用,因为
Compiler.compile()
是一个Java类,由标记为@CompileStatic
的Groovy类调用。这意味着当process()
调用Google的Compiler.compile()
时,不使用Groovy的MOP。甚至ClosureCompilerProcessor.translateMinifyOptions()
(Groovy代码)也无法被拦截,因为该类是@CompileStatic
。唯一可以拦截的方法是ClosureCompilerProcessor.process()
。fork 谷歌的closures-compiler.jar是我最后的丑陋手段。但是就像@Chad在下面说的那样,仅在正确的位置插入
options.setInlineFunctions(Reach.NONE)
并不能使我的内联JS函数名称复活。我试图将其他选项(例如setRemoveDeadCode=false
)切换为无效。我意识到乍得所说的是对的。我最终会四处翻转设置,并可能破坏缩小的工作方式。我的解决方案:我用UglifyJS预压缩了ext-all-debug.js并将它们添加到我的项目中。我可以将文件
ext-all-debug.min.js
命名为更干净,但是我没有。以下是我放置在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'
]
做完了问题解决了。
关键字:缩小,缩小,uglify,UglifyJS,UglifyJS2
最佳答案
在这种情况下,您将需要对编译器进行自定义构建或使用Java API。
但是-禁用内联不足以使其安全。重命名和无效代码删除也会引起问题。这违反了编译器的核心假设。仅在字符串内引用此局部函数。
此代码仅对编译器的WHITESPACE_ONLY
模式安全。
关于javascript - 有没有办法告诉Google Closure Compiler *不要*内联我的本地函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36929970/