Чи слід видаляти console.log із виробничого коду?


86

На даний момент я маю цей вираз JS скрізь у своєму коді:

window.console && console.log("Foo");

Мені цікаво, чи це взагалі дорого або має якісь негативні побічні ефекти у виробництві.

Чи можу я залишити вхід на стороні клієнта або це повинно піти?

EDIT: Зрештою, я вважаю, що найкращим аргументом, який я (і ще хтось?) Можу придумати, є те, що між сервером і клієнтом передається можливо незначна кількість додаткових даних, залишаючи повідомлення про реєстрацію. Якщо виробничий код повинен бути повністю оптимізований, журналювання доведеться видалити, щоб зменшити розмір javascript, що надсилається клієнту.


Відповіді:


41

Ви повинні НЕ додавати кошти розробки на сторінку продукції.

Щоб відповісти на інше питання: Код не може мати негативний побічний ефект:

  • window.consoleоцінить як false, якщо consoleне визначено
  • console.log("Foo")надрукує повідомлення на консолі, коли воно визначено (за умови, що сторінка не перезаписується console.logне функцією).

43
Я з вами в принципі згідний. Але, я думаю, ми всі погодимось, що впровадження журналювання, яке не запускається, крім режиму налагодження, необхідне для якісного коду на стороні сервера. Ніхто не проходить і не видаляє свої журнали для виробничого випуску - програма визначає, який рівень реєстрації необхідний, і реагує відповідно. Я сподівався б, що є щось подібне до цього для програмування на стороні клієнта ... навіть просто встановлення змінної "isDebug", якщо це необхідно. Чому я хотів би обтяжувати наступного розробника, вимагаючи повернення назад і повторного додавання журналів для проблемних областей у майбутньому?
Шон Андерсон,

11
Пошарпаний як? Я стверджую, що сказати, що консоль розробника є частиною робочого веб-сайту, все одно, що сказати, що файли журналів є частиною програми. Так, вони обидва генеруються кодом, але повинен бути певний рівень розуміння того, що журнали потрібно десь залишати. Інше питання, чи є висловлення всередині журналів зручними для користувача чи ні.
Шон Андерсон,

4
Як можна автоматично видалити код налагодження перед мінімізацією? Існує велика кількість форм, які може приймати повідомлення журналу на стороні клієнта.
Шон Андерсон,

6
Ви можете позначити кожну частину коду налагодження, наприклад, за допомогою префікса / постфіксації рядка коду налагодження коментарем. Приклад: /*DEBUG:start*/console.log("Foo");/*DEBUG:end*/. Потім використовуйте RegExp, щоб видалити всі випадки /*DENUG-start*/[\S\s]*?/*DEBUG-end*/. Залишилися пробіли символи мінімізатор видалить.
Роб W

3
Якщо ця відповідь не говорить ЧОМУ не слід цього робити, це насправді не корисно. Ми просто повинні сліпо визнати, що це погано, не маючи доказів чи причин?
ESR

48

Іншим способом вирішення цього є "заглушення" об'єкта консолі, коли він не визначений, тому помилки не виникають у контекстах, що не мають консолі, тобто

if (!window.console) {
  var noOp = function(){}; // no-op function
  console = {
    log: noOp,
    warn: noOp,
    error: noOp
  }
}

Ви отримуєте ідею ... Є багато функцій , визначені на різних реалізаціях консолі, так що ви можете незавершені їх все або тільки ті , які ви використовуєте (наприклад , якщо ви тільки коли - або використовувати console.logі ніколи не використовували console.profile, і console.timeт.д ...)

Для мене це краща альтернатива у розробці, ніж додавання умов перед кожним дзвінком або їх не використання.

див. також: Чи погано залишати дзвінки "console.log ()" у своєму продукті на коді JavaScript?


6
Гарна ідея. Потрібні лише деякі виправлення. Налагоджувач Visual Studio JS видає перший console.log = noOp (), оскільки сам об'єкт консолі не визначений. Я зробив це так: console = {log: noOp, warn: noOp, error: noOp}. Також зверніть увагу, що ви не хочете ставити () після noOp - ви хочете призначити саму функцію, а не її повернене значення. Перевірено на налагоджувачі Visual Studio JS та IE9 - тепер він працює нормально.
JustAMartin

3
FYI, якщо ви вже використовуєте JQuery, вони забезпечують функцію Nööp: $.noop.
розчавити

28

UglifyJS2

Якщо ви використовуєте цей мініфер, ви можете встановити drop_consoleопцію :

Передайте true, щоб відхилити виклики до консолі. * Функції

Тому я пропоную залишити console.logдзвінки, оскільки вони є для найскладнішої частини кодової бази.


3
Якщо ви використовуєте grunt і uglify , також доступна та сама опція (схоже, uglify базується на UglifyJS2): github.com/gruntjs/…
Tilt

1
Питання в тому, "чи повинен я", а не в "як мені".
ESR

Вам слід залишити console.errors у. Якщо хтось на виробництві має проблему, ви можете легко діагностувати її. Не знімайте console.errors!
Олівер Уоткінс,

Якщо буде необхідність у них , то ви можете просто встановити , drop_consoleщоб falseдотримуватися їх і знову приховати їх.
тералес

16

Якщо мініфікація є частиною вашого процесу збірки, ви можете використовувати її для видалення налагоджувального коду, як пояснено тут із компілятором закриття Google: Виключіть налагоджувальний код JavaScript під час мініфікації

if (DEBUG) {
  console.log("Won't be logged if compiled with --define='DEBUG=false'")
}

Якщо ви компілюєте з розширеною оптимізацією, цей код буде навіть визначено мертвим і повністю видалений


1
Дякую! Я шукав це. :)
Шон Андерсон,

5

Так. console.log видасть виняток у браузерах, які не мають для нього підтримки (об’єкт консолі не буде знайдений).


не з його оцінкою короткого замикання, доки визначено вікно
Джо

1
Хоча я пропустив це у своїй початковій відповіді, слід також перевірити console.log.
MK_Dev

Я в основному просто роблю window.console, щоб запобігти клопоту з IE. Я ще не стикався з ситуацією, коли журнал ненавмисно перевизначувався, але я впевнений, що це може статися.
Шон Андерсон,

@MK_Dev А саме, які браузери?
goodpixels

Це 2019 рік. Я сумніваюся, що є браузери, які не підтримують консоль.
Олівер Уоткінс,

5

Як правило, так, це не найкраща ідея виставляти повідомлення журналу у ваш робочий код.

В ідеалі вам слід видалити такі повідомлення журналу за допомогою сценарію збірки перед розгортанням; але багато (більшість) людей не використовують процес складання (включаючи мене).

Ось короткий фрагмент коду, який я використовував останнім часом, щоб вирішити цю дилему. Він виправляє помилки, спричинені невизначеною consoleстарою версією IE, а також вимикає ведення журналу, якщо в "development_mode".

// fn to add blank (noOp) function for all console methods
var addConsoleNoOp =  function (window) {
    var names = ["log", "debug", "info", "warn", "error",
        "assert", "dir", "dirxml", "group", "groupEnd", "time",
        "timeEnd", "count", "trace", "profile", "profileEnd"],
        i, l = names.length,
        noOp = function () {};
    window.console = {};
    for (i = 0; i < l; i = i + 1) {
        window.console[names[i]] = noOp;
    }
};

// call addConsoleNoOp() if console is undefined or if in production
if (!window.console || !window.development_mode) {
    this.addConsoleNoOp(window);
}

Я майже впевнений, що взяв більшу частину наведеного вище addConsoleNoOpf'n з іншої відповіді на SO, але зараз не можу знайти. Я додам посилання пізніше, якщо знайду.

редагувати: Не пост, про який я думав, але ось подібний підхід: https://github.com/paulmillr/console-polyfill/blob/master/index.js


3
var AppLogger = (function () {
  var debug = false;
  var AppLogger = function (isDebug) {
    debug = isDebug;
  }
  AppLogger.conlog = function (data) {
    if (window.console && debug) {
        console.log(data);
    }
  }
  AppLogger.prototype = {
    conlog: function (data) {
        if (window.console && debug) {
            console.log(data);
        }
    }
  };
return AppLogger;
})();

Використання:

var debugMode=true;
var appLogger = new AppLogger(debugMode);
appLogger.conlog('test');

1

Так, його хорошу практику використовувати console.logз метою налагодження javascript, але її потрібно видалити з робочого сервера або, якщо потрібно, можна додати на виробничий сервер з деякими ключовими моментами, які слід врахувати:

**var isDebugEnabled="Get boolean value from Configuration file to check whether debug is enabled or not".**
if (window.console && isDebugEnabled) {
    console.log("Debug Message");
}

Вищезазначений блок коду потрібно використовувати скрізь для ведення журналу, щоб спочатку перевірити, чи підтримується консоль для поточного браузера і чи увімкнено налагодження чи ні.

isDebugEnabled має бути встановлено як істинне чи хибне залежно від нашого середовища.


1

TL; DR

Ідея: журналювання об’єктів не дозволяє їм збирати сміття.

Деталі

  1. Якщо ви console.logпередаєте об'єкти, тоді ці об'єкти доступні за посиланням із консолі DevTools. Ви можете перевірити це, реєструючи об'єкт, мутуючи його та виявляючи, що старі повідомлення відображають пізніші зміни об'єкта.
  2. Якщо журнали занадто довгі, старі повідомлення видаляються в Chrome.
  3. Якщо журнали короткі, то старі повідомлення не видаляються, якщо ці повідомлення посилаються на об'єкти, тоді ці об'єкти не є зібраним сміттям.

Це просто ідея: я перевірив пункти 1 і 2, але не 3.

Рішення

Якщо ви хочете вести журнали для усунення неполадок на стороні клієнта або інших потреб, тоді:

['log', 'warn', 'error'].forEach( (meth) => {
  const _meth = window.console[meth].bind(console);
  window.console[meth] = function(...args) { _meth(...args.map((arg) => '' + arg)) }
});

0

В основному я перезаписую функцію console.log тією, яка має знання про те, де виконується код. Таким чином, я можу продовжувати використовувати console.log, як завжди. Він автоматично знає, що я перебуваю в режимі dev / qa або на виробництві. Є також спосіб змусити це. Ось робоча скрипка. http://jsfiddle.net/bsurela/Zneek/

Ось фрагмент, коли переповнення стека інформується людьми, які публікують jsfiddle

  log:function(obj)
{
    if(window.location.hostname === domainName)
    {
        if(window.myLogger.force === true)
        {
            window.myLogger.original.apply(this,arguments);
        }
    }else {
        window.myLogger.original.apply(this,arguments);
    }
},

0

Я знаю, що це досить давнє запитання, і я давно не мав особливої ​​активності. Я просто хотів додати своє рішення, яке я придумав, яке, здається, працює для мене досить добре.

    /**
     * Logger For Console Logging 
     */
    Global.loggingEnabled = true;
    Global.logMode = 'all';
    Global.log = (mode, string) => {    
        if(Global.loggingEnabled){
            switch(mode){
              case 'debug':
                  if(Global.logMode == 'debug' || Global.logMode == 'all'){
                    console.log('Debug: '+JSON.stringify(string));
                  }
                  break;
              case 'error':
                  if(Global.logMode == 'error' || Global.logMode == 'all'){
                    console.log('Error: '+JSON.stringify(string));
                  }       
                  break;
              case 'info':
                  if(Global.logMode == 'info' || Global.logMode == 'all'){
                    console.log('Info: '+JSON.stringify(string));
                  }
                  break;
            }
        }
    }

Тоді я зазвичай створюю функцію в своїх сценаріях, як це, або ви можете зробити її доступною в глобальному сценарії:

Something.fail = (message_string, data, error_type, function_name, line_number) => {
    try{

        if(error_type == undefined){
            error_type = 'error';
        }

        Global.showErrorMessage(message_string, true);
        Global.spinner(100, false);

        Global.log(error_type, function_name);
        Global.log(error_type, 'Line: '+line_number);
        Global.log(error_type, 'Error: '+data);

    }catch(error){
        if(is_global){
            Global.spinner(100, false);
            Global.log('error', 'Error: '+error);
            Global.log('error', 'Undefined Error...');
        }else{
            console.log('Error:'+error);
            console.log('Global Not Loaded!');
        }           
    }   
}

І тоді я просто використовую це замість console.log так:

try{
 // To Do Somehting
 Something.fail('Debug Something', data, 'debug', 'myFunc()', new Error().lineNumber);
}catch(error){
 Something.fail('Something Failed', error, 'error', 'myFunc()', new Error().lineNumber);
}

0

Якщо робочий процес виконується за допомогою правильних інструментів, таких як parcel/, webpackце вже не головний біль, оскільки productionзбірка відпадає console.log. Навіть кількома роками раніше з Gulp/ Gruntце також могло бути автоматизовано.

Багато хто з сучасних систем , такі , як Angular, React, Svelte, Vue.jsприходять до цієї установки поза коробки. По суті, вам не потрібно нічого робити, доки ви розгортаєте правильну збірку, тобто productionтаку, developmentяка ще не буде console.log.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.