2013-05-15 3 views
1

Я использую Google Closure Compiler в проекте Drupal прямо сейчас. Мой Javascript структурирован с использованием Javascript Module Pattern.Javascript Module Pattern и Google Closure Compiler

Из-за того, как работает Drupal, я собираю каждый JS-файл по отдельности. Режим простой компиляции работает хорошо, но я хотел бы использовать Advanced Compilation для каждого файла.

Мои файлы все вариации на

var FOO = (function(me, $, Drupal, undefined) { 
    function init (context, settings) { 
    do_sutff(); 
    }; 

    Drupal.behaviors['FOO'] = { 
    attach: init 
    }; 

    return me; 
}(FOO || {}, jQuery, Drupal)); 

Моя проблема заключается в том, что Drupal.behaviors является конкретный объект в Drupal и attach свойство также является специфическим свойством. Когда страница Drupal отображается, Drupal.behaviors получает петлю, и все функции attach вызываются с соответствующими аргументами. Другими словами, я не хочу что-нибудь переименовано в объект Drupal.

При использовании режима Advanced компиляции, я получаю

var c = function(a, d, b) { 
    b.b.FOO = {a:function() { 
    do_stuff() 
    }}; 
    return a 
}(c || {}, jQuery, Drupal); 

Я пробовал много вариаций на попытку получить компилятор распознавать весь Drupal объект как экстерн без удачи. Независимо от того, что я пытаюсь, .behaviors и .attach всегда переименовываются.

Есть ли способ рассказать компилятору, что руки не могут быть удалены из целого объекта?

+0

i get b.behaviors.FOO = {attach: function() {}}; ... – dandavis

+0

@ dandavis Я получаю это с SIMPLE_OPTIMIZATIONS. Когда я использую ADVANCED_OPTIMIZATIONS, объект «Drupal» становится обработанным, как показывает редактирование. – mpdonadio

+0

var o = Drupal ['behaviors'] ['FOO']; о [ 'прикрепить'] = INIT; – dandavis

ответ

5

Нет понятия «Не изменяйте свойства этого объекта». Однако вы можете настроить экстерном, такие как:

/** @interface */ 
function DrupalBehavior() {} 
DrupalBehavior.prototype.attach = function(){}; 

/** @constructor */ 
function DrupalObject() {} 

/** @type {Object.<string, DrupalBehavior>} */  
DrupalObject.prototype.behaviors = {}; 

Затем в коде:

var FOO = (
    /** 
    * @param {Object} me 
    * @param {jQuery} $ 
    * @param {DrupalObject} Drupal 
    * @param {*=} undefined 
    */ 
    function(me, $, Drupal, undefined) { 
    function init (context, settings) { 
     do_sutff(); 
    }; 
    Drupal.behaviors['FOO'] = { 
     attach: init 
    }; 

    return me; 
    }(FOO || {}, jQuery, Drupal)); 

В этом случае аргумент Drupal будет переименован, но behaviors свойство и связанное с ним attach суб-недвижимость не будет.

Одна заметка о jQuery: вы передаете объект пространства jQuery в функцию как параметр . Closure-компилятор не отслеживает тип объекта в этом объекте. Аннотации, которые я перечислял, были бы для объекта jQuery, а не для всего пространства имен jQuery. Вероятно, это не то, что вы намеревались. Единственный безопасный для использования тип в компиляторе Closure - это НЕ пропускать пространства имен через закрытие функции.

Обновление: после просмотра ссылки на модуль модуля JavaScript, которую вы связываете, они поощряют передачу объектов глобального пространства имен в закрытие функций. Этот шаблон имеет проблемы с Closure-компилятором. Вам нужно будет выбрать либо следовать шаблону в этом отношении, либо выбрать полную совместимость с ADVANCED_OPTIMIZATIONS.

+0

Спасибо, я проверил это завтра. Является ли последний абзац истинным, когда jQuery находится в режиме noConflict? Это и есть причина для параметра. – mpdonadio

+0

Да. Способ справиться с этим - это опция 'output_wrapper' Closure-компилятора. Вы бы использовали что-то вроде: '--output_wrapper =" (function (jQuery) {% output%}) (jQuery.noConflict()) "' –