,这是我要找的:
有疑问的形式:
CompilationLevel.SIMPLE_OPTIMIZATIONS,它可以完成我想做的任何事情,除了它在内联我的本地函数。在我的javascript文件的顶部有一些指令是很酷的,例如:
// This is a JS comment...
// google.closure.compiler = [inlineLocalFunctions: false]我正在开发一个Grails应用程序并使用Grails资产管道插件,它使用Google闭包编译器(以下简称Compiler)。该插件支持编译器通过Grails配置grails.assets.minifyOptions支持的不同的小型化级别。这允许‘简单’,‘高级’,‘白空间_只’。
AssetCompiler.groovy (资产管道插件)调用ClosureCompilerProcessor.process()
它最终在SIMPLE_OPTIMIZATIONS对象上分配CompilerOptions。通过这样做,CompilerOptions.inlineLocalFunctions = true作为副产品(这是编译器中的硬编码行为)。如果我使用WHITESPACE_ONLY,结果将是inlineLocalFunctions=false。
因此,通过使用资产管道的“简单”设置,本地函数正在内联,这给我带来了麻烦。示例: ExtJS ext-all-debug.js,它使用大量的本地函数。
因此,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:在类似帖子(某些功能?)中的响应并不能解决我的问题,因为我需要大量的内联函数。我已经解释过这一点了。
以我前面提到的ExtJS文件为例,说明为什么上面的类似的SO不能解决我的问题。查看ext-all-debug.js的原始代码。查找byAttribute()函数。然后继续查找字符串"byAttribute“,您将看到它是正在定义的字符串的一部分。我不熟悉这段代码,但我假设这些基于字符串的byAttribute值稍后将传递给JS()函数执行。当byAttribute是字符串的一部分时,编译器不会改变它的这些值。一旦function byAttribute内联,调用函数的尝试就不再可能了。
UPDATE3: I尝试了两种策略来解决这个问题,但都失败了。然而,我成功地实现了一个解决方案。我的尝试失败了
com.google.javascript.jscomp.Compiler.compile()。com.google.javascript.jscomp.applySafeCompilationOptions()而不是本地设置来修改options.setInlineFunctions(Reach.NONE);。方法拦截不起作用,因为Compiler.compile()是一个被标记为@CompileStatic的Groovy类调用的Java类。这意味着在process()调用谷歌的Compiler.compile()时不使用Groovy的拖把。即使是ClosureCompilerProcessor.translateMinifyOptions() (Groovy代码)也不能被拦截,因为类是@CompileStatic。唯一能被拦截的方法是ClosureCompilerProcessor.process()。
分叉谷歌的闭包编译器. was是我最后丑陋的选择。但是就像@Chad在下面所说的,简单地在正确的位置插入options.setInlineFunctions(Reach.NONE)并没有复活我的内联JS函数名。我试图切换其他选项,如setRemoveDeadCode=false,但没有结果。我意识到查德说的没错。我最终会翻转周围的设置,并可能破坏小型化的工作方式。
我的解决方案:,我用UglifyJS预压缩了ext-all调试器,并将它们添加到我的项目中。我本可以将文件命名为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'
]好了。问题解决了。
关键词:小型化,小型化,丑陋,UglifyJS,UglifyJS2
发布于 2016-05-01 17:32:02
在这种情况下,您需要对编译器进行自定义构建,或者使用Java。
然而-禁用内联是不够的,以确保这一安全。重命名和死代码消除也会导致问题。这违反了编译器的核心假设。此本地函数仅从字符串中引用。
此代码仅对编译器的WHITESPACE_ONLY模式是安全的。
发布于 2018-04-11 19:57:05
https://stackoverflow.com/questions/36929970
复制相似问题