Подтвердить что ты не робот

Использовать функции журнала ловушки компилятора Closure



У меня есть API протоколирования, который я хочу открыть для некоторого внутреннего JS-кода. Я хочу иметь возможность использовать этот API для регистрации, но только тогда, когда я делаю сборку отладки. Сейчас я частично работаю. Он регистрируется только на отладочных сборках, но вызовы этого API все еще находятся в коде при регулярной сборке. Я хотел бы, чтобы компилятор-замыкатель удалял этот по существу мертвый код, когда компилятор с goog.DEBUG = false.

Определение журнала:

goog.provide('com.foo.android.Log');
com.foo.Log.e = function(message){
    goog.DEBUG && AndroidLog.e(message);
}
goog.export(com.foo.Log, "e", com.foo.Log.e);

AndroidLog - это объект Java, предоставляемый веб-просмотру, который будет запущен и правильно выведен следующим образом:

var AndroidLog = {};

/**
 * Log out to the error console
 * 
 * @param {string} message The message to log
 */
AndroidLog.e = function(message) {};

Затем в моем коде я могу использовать:

com.foo.Log.e("Hello!"); // I want these stripped in production builds

Мой вопрос заключается в следующем: как я могу предоставить этот API, использовать этот API по всему моему коду, но затем удалить любые вызовы этого API, если они не скомпилированы с goog.DEBUG = true? Прямо сейчас, моя база кода раздувается с кучей вызовов в Log API, которые никогда не вызываются. Я хочу удалить.

Спасибо!

4b9b3361

Ответ 1

ОК, получается, что это легко сделать, если я прекращаю экспорт com.foo.Log() и его методов. Если я действительно хочу иметь возможность регистрироваться в некоторых конкретных случаях, но все равно изгоняю вызовы журнала во внутреннем коде, я могу просто объявить для этого два класса:

// This will get inlined and stripped, since its not exported.
goog.provide('com.foo.android.Log');
com.foo.Log.e = function(message){
    goog.DEBUG && AndroidLog.e(message);
}
// Don't export.


// This be available to use after closure compiler runs, since it exported.
goog.provide('com.foo.android.production.Log');
goog.exportSymbol("ProductionLog", com.foo.android.production.Log);
com.foo.android.production.Log.log = function(message){
    goog.DEBUG && AndroidLog.e(message);
}
// Export.
goog.exportProperty(com.foo.android.production.Log, "log", com.foo.android.production.Log.log);

Ответ 2

Компилятор Closure предоставляет четыре опции в CompilerOptions.java для разметки кода: 1) stripTypes, 2) stripNameSuffixes, 3) stripNamePrefixes и 4) stripTypePrefixes. Инструмент сборки Closure plovr предоставляет stripNameSuffixes и stripTypePrefixes через его конфигурационные параметры JSON name-suffixes-to-strip и type-prefixes-to-strip.

Есть отличные примеры того, как эти параметры работают в Closure: Полное руководство на страницах с 442 по 444. В качестве общих случаев используются следующие строки:

options.stripTypePrefixes = ImmutableSet.of("goog.debug", "goog.asserts");
options.stripNameSuffixes = ImmutableSet.of("logger", "logger_"); 

Чтобы понять нюансы этих параметров и избежать потенциальных ошибок, я настоятельно рекомендую прочитать полные примеры в "Закрытии: окончательное руководство".

Ответ 3

Вместо того, чтобы запускать свой собственный script, как предлагал jfriend00, я бы посмотрел на определение api компилятора (с которого также появляется goog.DEBUG), у вас есть DEBUG, COMPILED по умолчанию, но там вы можете перевернуть ваш собственный.

Ответ 4

Я изменил компилятор и упаковал его как пакет npm.

Вы можете получить его здесь: https://github.com/thanpolas/superstartup-closure-compiler#readme

Он будет разбивать все сообщения журнала во время компиляции