Удаление кода отладки внутри функции с помощью простых оптимизаций Closure Compiler

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

/** @define {boolean} */
var DEBUG = true;

if (DEBUG) {
    console.log('remove me');
}

Простая оптимизация с помощью --define='DEBUG=false'уменьшает это до var DEBUG=!1;. То же самое относится и к этому:

/** @const */
var DEBUG = false;

if (DEBUG) {
    console.log('remove me');
}

Проблемы возникают при использовании этого соглашения внутри функции :

/** @const */
var DEBUG = false;

function logMe() {
    if (DEBUG) {
        console.log('remove me');
    }
}

. Это сводится к следующему:

var DEBUG=!1;function logMe(){DEBUG&&console.log("remove me")};

Я ожидаю, что он уменьшится до:

var DEBUG=!1;function logMe(){};

Есть ли причина, по которой это не работает должным образом? На самом деле я просто ищу чистый способ убрать код отладки и не готов погрузиться в расширенную оптимизацию.

Обновление

Согласно ответу @John,Я реализовал свой собственный компилятор и обнаружил, что следующая конфигурация удалит if (DEBUG) {}внутри и снаружи кода для случая@define:

CompilerOptions options = new CompilerOptions();
CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
//options.setInlineConstantVars(true);
options.setInlineVariables(CompilerOptions.Reach.ALL);
options.setDefineToBooleanLiteral("DEBUG", false);

Это работает достаточно хорошо для одного файла со следующими ограничениями:

  1. Это требует определения var DEBUGв каждом файле, что является плохой практикой.
  2. При объединении нескольких файлов у вас может быть только один var DEBUG, иначе компилятор не сможет его оптимизировать. Этого можно избежать, скомпилировав каждый файл по отдельности и объединив их.
  3. Поскольку значение определено в начале файла, получить его заранее невозможно.

Я обдумывал идею удалить все var DEBUGопределения из файлов и внедрить их в исходный или внешний перед выполнением, но столкнулся с двумя проблемами:

  • Определение его в extern, похоже, ничего не делает.
  • Undefined DEBUGв нескомпилированном коде вызывает ошибку ссылки в браузере.

Идеальным вариантом будет тест window.DEBUG, который не выдает ошибку ссылки. К сожалению, в то время как внедрение /** @const */ var window = {}; /** @const */ window.DEBUG = false;работает на верхнем уровне, уменьшая if (window.DEBUG) {}, оптимизация фактически отменяется, если она помещена в функцию.

Если другой вариант компилятора не работает, единственный вариант, который действительно имеет смысл, - это использовать window.DEBUGи перед компиляцией вводить /** @const */ var DEBUG = false;и глобально заменять /\bwindow.DEBUG\b/на DEBUG. Есть ли способ лучше?

8
задан Community 23 May 2017 в 10:29
поделиться