2013-03-24 2 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); 
}; 

почему-то Closure Compiler ссылается H .sa.xa.RECENT_ITEMS вместо х .sa.xa.RECENT_ITEMS

Любая причина, почему компилятор делает это это?

+4

Вероятно, вы получите лучший ответ, если вы продемонстрируете нарушающий код и его контекст. В Closure есть способы указать, что некоторые переменные не должны переименовываться, потому что они ссылаются снаружи. – jfriend00

+0

Я не могу воспроизвести проблему с этим фрагментом кода. Однако я бы попробовал НЕ передавать ваше пространство имен 'nam' в качестве аргумента для ваших анонимных оберток функций и посмотреть, не возникла ли проблема. –

+0

Выглядит хорошо для меня. Возможно, старая версия компилятора Plovr кусает вас или одну из ее настроек. Но, как правило, анонимные закрытия вокруг goog.provides необычны для кода Closure. – John

ответ

0

Единственный способ, которым я могу интерпретировать ваш вопрос в том, что одна из двух вещей происходит:

  1. Существует проблема с запутывания Замыкание составителей и минимизируя кода или
  2. Ошибка вы видите, из JavaScript, выполняющегося за пределами кода, скомпилированного компилятором Closure, который напрямую ссылается на скомпилированную переменную.

Если это первый, вы должны изолировать корпус, вызывающий переменную несоосность, и submit it as a bug to Google. Все мы, используя компилятор Closure, очень оценили бы это.

Если вместо этого, как я подозреваю, это последний, вы, скорее всего, не , экспортируя глобальную переменную, которую вы хотите использовать за пределами скомпилированного кода. Самый простой способ сделать это - вызвать функцию goog.exportSymbol(), чтобы сделать глобальную переменную доступной вне вашего кода, собранной компилятором Closure. Например, если вы хотели бы получить доступ к свойству sandwich.meat.Ham в скомпилированном режиме из нескомпилированной коды, вы можете сделать следующее:

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

Тогда вы могли бы иметь некоторый код, который существует вне скомпилированного кода, который ссылается на экспортируемом переменная:

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

Благодарим вас за помощь. Похоже, что это проблема с запутыванием и минимизацией кода. Я обновил сообщение, чтобы показать код нарушения. – Chris

0

Позвольте мне угадать, что вы делаете: скомпилировать каждый файл независимо в режиме ADVANCED. Если это так, то не работает режим ADVANCED. В расширенном режиме, если вы хотите использовать переменные и свойства между заданиями компиляции, вам необходимо экспортировать их.

+0

Я использую Plovr для компиляции кода, и все входные JS-файлы скомпилированы вместе – Chris

0

В приведенном ниже примере кода есть гораздо более серьезные проблемы.Для одного

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

был превращен в

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

Yet позже этот код:

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

был превращен в

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

Где можно было бы ожидать, что она должна быть

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

Кроме того, тот факт, что вы используете nam в качестве базового пространства имен для обоего половин неоткомпилированной коды и что он получает повернутую в отдельные x и H пространств имен, соответственно, также свидетельствует о более находится в игре. Некоторые предложения:

  • Если вы хотите использовать module шаблон, положить обеспечивают/требуют утверждения вне модуля
  • Не вручную создать пространство имен с вещами, как var nam = nam || {}, потому что обеспечивают делает это для вас уже
  • Как уже упоминалось, как файлы, содержащие nam.jsConfig и nam.util.cookie должны быть включены в одну компиляцию
  • Убедитесь, что вы goog.require('nam.jsConfig') в файле с nam.util.cookie.readMyCookie, чтобы обеспечить требования зависимостей выполнены

FWIW, мы используем закрытие в обширном приложении с сотнями файлов, содержащих взаимозависимости, подобные этому. Я бы очень сомневался, что проблема заключается не в инструментах, а в том, как они используются.

Смежные вопросы