2012-03-21 25 views
12



我有一个日志API我想暴露给一些内部的JS代码。我希望能够使用这个API来记录,但只有当我正在进行调试版本。现在,我已经部分工作了。它只会记录调试版本,但在定期编译时,对该API的调用仍在代码中。我希望封闭编译器在我使用goog.DEBUG = false进行编译时移除这个基本上无效的代码。使闭包编译器带日志功能的用法

登录定义:

goog.provide('com.foo.android.Log'); 
com.foo.Log.e = function(message){ 
    goog.DEBUG && AndroidLog.e(message); 
} 
goog.export(com.foo.Log, "e", com.foo.Log.e); 

AndroidLog是提供给网页视图,这将在运行一个Java对象,并妥善externed这样的:

var AndroidLog = {}; 

/** 
* Log out to the error console 
* 
* @param {string} message The message to log 
*/ 
AndroidLog.e = function(message) {}; 

然后,在我的代码,我可以使用:

com.foo.Log.e("Hello!"); // I want these stripped in production builds 

我的问题是这样的:我怎样才能提供这个API,使用此API都在我的代码,但则h当没有编译goog.DEBUG = true时,是否删除了对此API的任何调用?现在,我的代码库变得越来越臃肿,对一些从不被调用的Log API的调用。我想要删除。

谢谢!

+0

OK,经过一些进一步深挖,看来externed功能不被内联。 http://code.google.com/p/closure-compiler/issues/detail?ID = 230 我还是想找到一个比前面加上goog.DEBUG && – 2012-03-21 02:46:47

+0

每一个电话我用Python写了一个小脚本,自己剥夺我所有的调试封邮件出源作为我的生成过程的一部分以外的解决方法。当我需要它时,我也能找到一些东西。这很奇怪,因为它应该是这样一个共同的需求。 – jfriend00 2012-03-21 03:24:00

+0

是啊,我可你为什么要出口的“e”走这条路:) – 2012-03-21 03:42:23

回答

0

好的,事实证明,如果我停止导出com.foo.Log()及其方法,很容易做到这一点。如果我真的希望能够登录在某些特定情况下,但仍剔除在我的内部代码的日志调用,我可以只声明了两个类是:

// This will get inlined and stripped, since its not exported. 
goog.provide('com.foo.android.Log'); 
com.foo.Log.e = function(message){ 
    goog.DEBUG && AndroidLog.e(message); 
} 
// Don't export. 


// This be available to use after closure compiler runs, since it's exported. 
goog.provide('com.foo.android.production.Log'); 
goog.exportSymbol("ProductionLog", com.foo.android.production.Log); 
com.foo.android.production.Log.log = function(message){ 
    goog.DEBUG && AndroidLog.e(message); 
} 
// Export. 
goog.exportProperty(com.foo.android.production.Log, "log", com.foo.android.production.Log.log); 
0

而不是运行你自己的脚本jfriend00的建议我会看的编译器定义的API(这是goog.DEBUG来自为好),你有DEBUG,默认情况下编译,但是那里你可以推出自己的。

+1

这忽略了一点。重点不在于关闭调试输出(这很简单)。关键是在部署之前删除所有调试代码,以免它们占用额外的空间,执行甚至向世界展示。 – jfriend00 2012-03-21 09:50:30

+0

lennel,感谢您的建议。如前所述jfriend00,这只会让我在传递数据。我已经使用通过goog.DEBUG参数传递数据,和它是完全剥离的功能的机构。但是这个空白函数体不会内联到我的代码中去除函数的用法。我认为这是因为CC不能假定在运行时不会修改异常的函数? – 2012-03-21 17:17:03

+0

对不起,一直在度假。如果使用设置为false的define变量进行编译,则编译器将在高级模式下省略该代码。 – lennel 2012-03-26 11:07:40

1

的关闭编译器提供CompilerOptions.java四个选项剥离代码:1)stripTypes,2)stripNameSuffixes,3)stripNamePrefixes和4)stripTypePrefixes。 Closure构建工具plovr,通过其JSON configuration file optionsname-suffixes-to-striptype-prefixes-to-strip公开stripNameSuffixesstripTypePrefixes

有这些选项在闭合如何工作的很好的例子:在页面上权威指南 442至444以下行是作为常见的用例:

options.stripTypePrefixes = ImmutableSet.of(“goog.debug”, “goog.asserts”); 
options.stripNameSuffixes = ImmutableSet.of(“logger”, “logger_”); 

了解这些细微差别选项,并避免潜在的陷阱,我强烈建议阅读关闭:权威指南中的完整示例。

+0

谢谢!我应该提到我正在使用Closure Ant任务,因此无法直接传递编译器选项。我正在考虑,为了我自己的编译器选项传递继承Ant任务,但想先问清楚是否有事实上的方式来做到这一点。我也会看看plovr。 – 2012-03-26 08:01:50

+0

@SkyKelsey:上面提到的编译器选项剥离代码在Closure Compiler Java源代码内部,即CompilerOptions.java。然而,plovr使得它易于使用stripNameSuffixes和stripTypePrefixes无需编写Java代码。我目前正在为所有的Closure工具编写一套Ant任务,这将增加灵活性。希望他们将在2012年4月底前准备好发布。 – 2012-03-30 02:04:50