Ответ 1
здесь (окончательный) ответ для компилятора замыкания:
/** @const */
var LOG = false;
...
LOG && log('hello world !'); // compiler will remove this line
...
это будет работать даже с SIMPLE_OPTIMIZATIONS
и не требуется --define=
!
Я изучаю разные способы минимизации кода JavaScript, включая обычный JSMin, Packer и YUI. Мне действительно интересен новый Google Closure Compiler, поскольку он выглядит исключительно мощным.
Я заметил, что Пакер Dean Edwards имеет функцию, исключающую строки кода, начинающиеся с трех точек с запятой. Это удобно для исключения кода отладки. Например:
;;; console.log("Starting process");
Я потратил некоторое время на очистку своей кодовой базы и хотел бы добавить такие подсказки, чтобы легко исключить код отладки. Чтобы подготовиться к этому, я хотел бы выяснить, является ли это лучшим решением или существуют другие методы.
Поскольку я еще не выбрал способ минимизации, я хотел бы очистить код таким образом, который совместим с любым minifier, в котором я заканчиваю работу. Поэтому мои вопросы таковы:
Использует ли точка с запятой стандартную технику или есть другие способы сделать это?
Является ли Packer единственным решением, которое предоставляет эту функцию?
Могут ли другие решения быть адаптированы для работы таким образом, или у них есть альтернативные способы достижения этого?
В конце концов, я, вероятно, начну использовать Closure Compiler. Есть ли что-нибудь, что я должен сделать сейчас, чтобы подготовиться к этому?
здесь (окончательный) ответ для компилятора замыкания:
/** @const */
var LOG = false;
...
LOG && log('hello world !'); // compiler will remove this line
...
это будет работать даже с SIMPLE_OPTIMIZATIONS
и не требуется --define=
!
Вот что я использую с Closure Compiler. Во-первых, вам нужно определить переменную DEBUG следующим образом:
/** @define {boolean} */
var DEBUG = true;
Он использует аннотацию JS для закрытия, которую вы можете прочитать в в документации.
Теперь, когда вам нужен какой-то только отладочный код, просто оберните его в оператор if, например:
if (DEBUG) {
console.log("Running in DEBUG mode");
}
При компиляции кода для выпуска добавьте следующую команду компиляции: --define='DEBUG=false'
- любой код в инструкции отладки будет полностью оставлен вне скомпилированного файла.
Хорошим решением в этом случае может быть js-build-tools, который поддерживает "условную компиляцию".
Короче говоря, вы можете использовать комментарии, такие как
// #ifdef debug
var trace = debug.getTracer("easyXDM.Rpc");
trace("constructor");
// #endif
где вы определяете прагму, такую как debug
.
Затем при его создании (у него есть ant -task)
//this file will not have the debug code
<preprocess infile="work/easyXDM.combined.js" outfile="work/easyXDM.js"/>
//this file will
<preprocess infile="work/easyXDM.combined.js" outfile="work/easyXDM.debug.js" defines="debug"/>
Если вы используете компилятор Closure в расширенном режиме, вы можете сделать что-то вроде:
if (DEBUG) console.log = function() {}
Затем компилятор удалит все ваши вызовы console.log. Конечно, вам нужно --define
переменную DEBUG
в командной строке.
Однако это только для расширенного режима. Если вы используете простой режим, вам нужно запустить препроцессор в исходном файле.
Почему бы не рассмотреть набор инструментов Dojo? Он имеет встроенную прагму, основанную на комментариях, для включения/исключения разделов кода на основе сборки. Кроме того, он совместим с компилятором Closure в расширенном режиме (см. Ссылку ниже)!
Хотя это старый вопрос. Я наткнулся на ту же проблему сегодня и обнаружил, что ее можно достичь, используя CompilerOptions.
Я следил за этот поток.
Мы запускаем компилятор с Java на нашем сервере перед отправкой кода клиенту. Это работало для нас в простом режиме.
private String compressWithClosureCompiler(final String code) {
final Compiler compiler = new Compiler();
final CompilerOptions options = new CompilerOptions();
Logger.getLogger("com.google.javascript.jscomp").setLevel(Level.OFF);
if (compressRemovesLogging) {
options.stripNamePrefixes = ImmutableSet.of("logger");
options.stripNameSuffixes = ImmutableSet.of("debug", "dev", "info", "error",
"warn", "startClock", "stopClock", "dir");
}
CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
final JSSourceFile extern = JSSourceFile.fromCode("externs.js", "");
final JSSourceFile input = JSSourceFile.fromCode("input.js", code);
compiler.compile(extern, input, options);
return compiler.toSource();
}
Он удалит все вызовы logger.debug, logger.dev... и т.д.
Добавление логики ко всем местам вашего кода, где вы регистрируетесь на консоли, затрудняет отладку и обслуживание.
Если вы уже собираетесь добавить шаг сборки для своего производственного кода, вы всегда можете добавить еще один файл вверху, который превратит ваши методы console
в noop
.
Что-то вроде:
console.log = console.debug = console.info = function(){};
В идеале вы просто вычеркиваете любые методы console
, но если вы все равно их сохраняете, но не используете их, это, вероятно, проще всего работать с.
Если вы используете UglifyJS2, вы можете использовать аргумент drop_console для удаления консоли. * функции.
Я с @marcel-korpel. Не совершенен, но работает. Замените инструкции отладки перед минификсацией. Регулярное выражение работает во многих местах. Остерегайтесь незакрытых линий.
/console\.[^;]*/gm
Работает на:
;;; console.log("Starting process");
console.log("Starting process");
console.dir("Starting process");;;;;
console.log("Starting "+(1+2)+" processes"); iamok('good');
console.log('Message ' +
'with new line'
);
console.group("a");
console.groupEnd();
swtich(input){
case 1 : alert('ok'); break;
default: console.warn("Fatal error"); break;
}
Не работает:
console.log("instruction without semicolon")
console.log("semicolon in ; string");
До сих пор я не изучал минимизацию, но это поведение можно было выполнить с помощью простого регулярного выражения:
s/;;;.*//g
Это заменяет все в строке после (и в том числе) трех точек с запятой ничем, поэтому она отбрасывается перед ее изложением. Вы можете запустить sed
(или аналогичный инструмент), прежде чем запускать инструмент минимизации, например:
sed 's/;;;.*//g' < infile.js > outfile.js
Кстати, если вам интересно, будет ли упакованная версия или сокращенная версия "лучше", прочитайте это сравнение методов сжатия JavaScript.
Я использовал следующие самодельные stuf:
// Uncomment to enable debug messages
// var debug = true;
function ShowDebugMessage(message) {
if (debug) {
alert(message);
}
}
Итак, когда вы объявили переменную debug
, которая установлена на true
- все вызовы ShowDebugMessage()
вызывали бы также alert()
. Поэтому просто используйте его в коде и забывайте о таких условиях, как ifdef
или ручное комментирование строк вывода отладки.