Closure编译器混合变量名称

问题描述:

我有一个问题,其中Closure编译器重命名一个像x.sa.xa这样的全局变量,但是在引用该全局变量的所有函数中,编译器将其重命名为其他类似H.sa.xa的东西Closure编译器混合变量名称

当我查看HTML页面时,我得到一个JavaScript TypeError:H.sa.xa未定义。

// Top-level namespace for all the code 
var nam = nam || {}; 

(function($, nam) { 

goog.provide('nam.jsConfig'); 

nam.jsConfig.cookies = {"RECENT_ITEMS": "recentitems"}; 

})($, nam); 

(function($, nam) { 
goog.provide('nam.util.cookie'); 
nam.util.cookie.readMyCookie = function() { 
    var ritems_cookie = nam.util.cookie.JSONCookie.get(nam.jsConfig.cookies['RECENT_ITEMS']); 
}; 
})($, nam); 


Closure Compiled Code: 
x.sa = {}; 
x.sa.xa = {RECENT_ITEMS:"recentitems"}; 

H.a = {}; 
H.a.cookie = {}; 
H.a.Tm = function() { 
    var a = H.a.cookie.ja.get(H.sa.xa.RECENT_ITEMS); 
}; 

出于某种原因,关闭编译器所引用^h .sa.xa.RECENT_ITEMS代替X .sa.xa.RECENT_ITEMS

有什么理由编译器是这样做呢?

+4

如果您显示违规代码及其上下文,您可能会得到更好的回复。 Closure可以指定某些变量不应该被重命名,因为它们是在外部引用的。 – jfriend00 2013-03-24 15:44:17

+0

我无法重现该代码段的问题。不过,我会尝试不传递你的名字空间'nam'作为你的匿名函数包装的参数,并看看问题是否仍然存在。 – 2013-03-25 11:45:12

+0

对我来说也很好。也许Plovr的旧编译器版本咬你或它的一个定制。但通常,goog.provide周围的匿名闭包对于Closure代码来说并不常见。 – John 2013-03-26 15:05:38

我能理解你的问题的唯一方法是,一两件事情正在发生:

  1. 没有与关闭编译器的混淆和减少代码,或
  2. 您所看到的错误是一个问题来自在Closure Compiler编译的代码之外运行的JavaScript,它直接引用一个编译变量。

如果是前者,则应隔离导致变量未对齐的情况和submit it as a bug to Google。我们所有人都使用Closure编译器将非常感谢它。

如果相反,正如我怀疑的那样,它是后者,您很可能不是导出您希望在编译代码之外使用的全局变量。最简单的方法是调用goog.exportSymbol()函数使全局变量在由Closure Compiler组装的代码之外可用。例如,如果你想从非编译代码访问编译模式的属性sandwich.meat.Ham,你可以做到以下几点:

goog.exportSymbol('sandwich.meat.Ham', sandwich.meat.Ham); 

然后你可以有存在的已编译的代码引用出口以外的一些代码变量:

function() { 
    var meat = new sandwich.meat.Ham(); 
} 
+0

谢谢你的帮助。看起来这是一个混淆和最小化的代码问题。我已更新我的帖子以显示违规代码。 – Chris 2013-03-25 10:17:58

让我猜你在做什么:在ADVANCED模式下独立编译每个文件。如果是这样,这不是高级模式的工作原理。在高级模式下,如果要在编译作业之间共享变量和属性,则需要导出它们。

+0

我使用Plovr编译代码,并将所有输入的JS文件一起编译 – Chris 2013-03-26 03:20:25

您提供的代码示例中有更多重要的问题。对于一个

goog.provide('nam.util.cookie'); 

被辟为

H.a = {}; 
H.a.cookie = {}; 

然而,这后面的代码:

nam.util.cookie.readMyCookie = function() {... 

被辟为

H.a.Tm = function() {... 

当人们预期它应该是

H.a.cookie.Tm = function() {... 

此外,您使用nam为基础的命名空间的未编译代码的两半,它被变成了独立的xH命名空间的事实,也分别被建议更多的是在作怪。几点建议:

  • 如果您想使用module模式,把提供/需要的模块之外声明
  • 不要用手工制作的东西像命名空间,因为var nam = nam || {}提供为您完成此已经
  • 正如其他人所说,含有nam.jsConfignam.util.cookie这两个文件应包含在一个单一的编译
  • 确保您goog.require('nam.jsConfig')在文件中nam.util.cookie.readMyCookie,以确保依赖性需求得到满足

FWIW,我们使用封闭在一个广泛的应用与数百个文件,包含这样的相互依存关系。我会高度怀疑问题不在于工具,而在于如何使用它们。