Търся начин да премахна кода за отстраняване на грешки от функциите, за да мога да добавя тестови куки към затваряния. Прочетох Google Closure Compiler Advanced: премахване на кодови блокове по време на компилиране и тествано премахване на код за отстраняване на грешки със следното:
/** @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);
Това работи достатъчно добре за един файл със следните ограничения:
- Това изисква
var DEBUG
да бъде дефинирано във всеки файл, което е лоша практика. - Когато комбинирате множество файлове, можете да имате само един
var DEBUG
или компилаторът не може да оптимизира около него. Това може да се избегне чрез компилиране на всеки файл поотделно и тяхното сливане. - Тъй като стойността е дефинирана в началото на файла, няма гъвкавост за получаване на стойността предварително.
Играх си с идеята да премахна всички var DEBUG
дефиниции от файловете и да ги инжектирам в източника или extern преди изпълнение, но се натъкнах на два проблема:
- Дефинирането му във 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
. Има ли по-добър начин?
if
блокове на ниво скрипт. Опитвам се да разбера защо този подход не работи едно ниво надолу във функция. - person Brian Nickel♦   schedule 10.07.2012