2013-03-24 87 views
0

我有一個問題,其中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

回答

0

我能理解你的問題的唯一方法是,一兩件事情正在發生:

  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

0

讓我猜你在做什麼:在ADVANCED模式下獨立編譯每個文件。如果是這樣,這不是高級模式的工作原理。在高級模式下,如果要在編譯作業之間共享變量和屬性,則需要導出它們。

+0

我使用Plovr編譯代碼,並將所有輸入的JS文件一起編譯 – Chris 2013-03-26 03:20:25

0

您提供的代碼示例中有更多重要的問題。對於一個

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,我們使用封閉在一個廣泛的應用與數百個文件,包含這樣的相互依存關係。我會高度懷疑問題不在於工具,而在於如何使用它們。