【问题标题】:How can I tell the Closure Compiler not to rename an inner function using SIMPLE_OPTIMIZATIONS?如何告诉闭包编译器不要使用 SIMPLE_OPTIMIZATIONS 重命名内部函数?
【发布时间】:2012-02-29 01:17:40
【问题描述】:

如何告诉闭包编译器不要重命名内部函数?例如,给定以下代码:

function aMeaninglessName() {
    function someMeaningfulName() {
    }

    return someMeaningfulName;
}

...我对 Closure 重命名外部函数没问题(我积极希望它这样做,以节省空间),但我希望函数名称 someMeaningfulName 单独保留(以便调用堆栈中显示的名称为它是“someMeaningfulName”,而不是“a”或其他)。尽管调用它的代码将通过工厂函数返回的引用而不是代码中的名称来执行此操作。例如,这纯粹是为了调试支持。

请注意,我希望函数具有实际名称,而不是匿名的并使用该名称分配给某些属性,因此例如这不是this other question.

externs 或exports 功能似乎都没有涵盖这个有点晦涩的用例。 (我有点希望有一些annotation 我可以扔掉它。)但我不是闭包编译器大师,我希望你们中的一些人是。当然,如果没有办法做到这一点,这是一个可以接受的答案。


(用例是一个库,它创建函数以响应对其的调用。我想提供一个由 Closure 使用 SIMPLE_OPTIMIZATIONS 预压缩的库版本,但如果有人使用该库的副本他们自己的未压缩代码并在调试器[或其他类似操作]中单步进入函数,我希望他们看到有意义的名称。我可以用eval绕过它,或者手动编辑压缩结果[事实上,上下文足够独特,我可以向它扔一个sed 脚本],但这很尴尬,坦率地说,我们进入了“不值得打扰”的领域,因此寻找一种简单、低维护的方式。)

【问题讨论】:

    标签: google-closure-compiler


    【解决方案1】:

    没有简单的方法可以做到这一点。您必须创建 CodingConvention 类的自定义子类,以表明您的方法是“本地”外部(添加了对此的支持以处理 Prototype 库)。 InlineVariables、InlineFunctions 或 RemoveUsedVariables 可能仍会尝试删除名称,并且还需要修复。

    另一种方法是使用源映射将堆栈跟踪重新映射到原始源。

    【讨论】:

    • 所以如果我认为值得,我会使用我自己的本地定制版本的编译器,它有一个CodingConventions.Proxy 来包装默认编码约定,并覆盖......什么,@ 987654322@ 让它为该成员返回false
    • isExported(String name, boolean local) 是感兴趣的方法,特别是当“local”为真时。
    • 谢谢。那么我必须破解CommandLineRunner 来添加一个标志吗?从事物的外观来看,我可能想要包装或扩展ClosureCodingConvention 而不是默认值,以获得与我通常会得到的相同的行为加上我的特殊位。总的来说还不错,Closure 下载和构建没有任何麻烦。如果我真的很有野心,我可能会添加一个注释并将其作为补丁提供。
    • 我不知道这方面的任何礼仪。我的意思似乎是“如果您发现此信息有帮助,请不要忘记投票”。
    • 我是否也必须破解CommandLineRunner 之类的?
    【解决方案2】:

    阅读以下部分

    https://developers.google.com/closure/compiler/docs/api-tutorial3#export

    基本上有两个选项,使用 object['functionName'] = obj.functionName 或更好的方法 在 goog 对象上同时使用 exportSymbol 和 exportProperty,这是该对象的文档链接

    http://closure-library.googlecode.com/svn/docs/closure_goog_base.js.html

    -- 编辑 啊,我现在明白了,我的第一个答案对你来说不是那么好。编译器有一些有趣的标志,您可能感兴趣的是 DEBUG,您可以将变量传递给编译器,这将允许您通过日志记录删除一些调试注释,或者只是一个字符串,因为您使用的是简单模式,所以什么都不做。

    因此,如果您使用闭包,您可以针对开发版本进行调试,该版本只是一个已解决依赖关系的页面。我们还在代码中删除了以下内容

    if(DEBUG){
      logger.info('pack.age.info.prototype.func');
    }
    

    【讨论】:

    • 以前也有一个萤火虫插件,但现在已经不存在了。如果您通常使用闭包,我们倾向于构建一个仅解决依赖关系的开发版本(在 chrome 调试器中,您实际上然后看到整个类路径而不是像 Firebug 中的 Object)并具有以下类型的行在每个函数成员中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    相关资源
    最近更新 更多