Закрывающий компилятор обрабатывает определения внутри замыканий как переопределения

Я работал с Google Closure, пытаясь получить большой объем JavaScript для чистой компиляции для минимизации с помощью компилятора Google. Я столкнулся с проблемой, хотя:

goog.provide('test');
goog.provide('test2');

/**
 * @constructor
 */
test = function () {
    this.x = 10;
    this.y = 13;
};

(function () {
    /**
     * @constructor
     */
    test2 = function () {
        this.x = 10;
        this.y = 13;
    };
})();

Бывший в порядке. Последний генерирует постоянную ошибку переопределения:

JSC_CONSTANT_REASSIGNED_VALUE_ERROR. constant test2 assigned a value more than once at /home/hbrown/tmp/closure-test/foo.js line 16 : 10
BUILD FAILED: 1 error(s), 0 warning(s)

Есть ли какой-нибудь способ заставить компилятор plovr / closure разрешить эту конструкцию? Я посмотрел вокруг и ничего не нашел.


Позже: в следующем пункте, почему замыкание / пловр считает test2 константой? Я подозреваю, что это связано с созданием plovr / closure пространства имен для test2, когда вызывается goog.provide. было бы неплохо увидеть промежуточную форму, с которой он работает, когда генерирует ошибку.

3 ответа

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

Вы пробовали что-то вроде этого:

test2 = (function () {
    /**
     * @constructor
     */
    function inner_test2() {
        this.x = 10;
        this.y = 13;
    };

    // ...

    return inner_test2;
})();

Я бы не предположил, что это удобный рефакторинг, особенно если эта анонимная функция большая и сложная, но было бы интересно (вроде бы) увидеть, что именно смущает компилятор.

В зависимости от того, зачем вам нужна анонимная функция, вы можете попробовать заменить анонимную функцию на goog.scope

http://closure-library.googlecode.com/svn/docs/closure_goog_base.js.html

Объявите тест 2 вне функции закрытия, не назначая его:

var test2;

(function() {
    test2 = function(...

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

Немного из того, что вы получаете с Closure Compiler, на самом деле являются внутренними руководящими принципами внутреннего кода Javascript Google, благодаря его истории. Так, например, вы не можете использовать оператор with, потому что это противоречит политике, даже если вы, как общедоступный пользователь, просто хотите минимизировать свой код, и у вас может быть политика, которая позволяет использовать оператор with в вашей компании.

Тем не менее, я считаю, что не рекомендуется объявлять глобальные переменные внутри функций (даже если это допустимый Javascript). И было бы не так сложно написать сценарий, который будет искать /(\w[\w\d-]+) = function/ и объявив его с помощью var в верхней части оскорбительных файлов. И это, вероятно, приведет к тому, что все файлы, модифицированные таким образом, будут легче анализироваться кодировщиками, новыми для данного файла.

Оставшаяся опция - изменить код закрытого компилятора с открытым исходным кодом, чтобы он вместо ошибок предупреждал об этом нарушении политики Google JS.

Другие вопросы по тегам