Obecnie mam to oświadczenie JS wszędzie w moim kodzie:
window.console && console.log("Foo");
Zastanawiam się, czy jest to w ogóle kosztowne, czy ma jakieś negatywne skutki uboczne w produkcji.
Czy mogę zostawić logowanie po stronie klienta, czy powinno to odejść?
EDYCJA: Ostatecznie wydaje mi się, że najlepszym argumentem, jaki mogę wymyślić (i kogokolwiek innego?), Jest to, że istnieje prawdopodobnie nie do pominięcia ilość dodatkowych danych przesyłanych między serwerem a klientem, pozostawiając wiadomości logowania. Jeśli kod produkcyjny ma być w pełni zoptymalizowany, logowanie będzie musiało zostać usunięte, aby zmniejszyć rozmiar kodu JavaScript wysyłanego do klienta.
javascript
logging
Sean Anderson
źródło
źródło
Odpowiedzi:
Należy nie dodać narzędzi programistycznych do strony produkcyjnej.
Aby odpowiedzieć na inne pytanie: Kod nie może mieć negatywnego skutku ubocznego:
window.console
jeśliconsole
nie zostanie zdefiniowana, zostanie oceniona na falseconsole.log("Foo")
wydrukuje wiadomość na konsoli, gdy jest zdefiniowana (pod warunkiem, że strona nie zostanie zastąpionaconsole.log
przez niefunkcję).źródło
/*DEBUG:start*/console.log("Foo");/*DEBUG:end*/
. Następnie użyj RegExp, aby usunąć wszystkie wystąpienia/*DENUG-start*/[\S\s]*?/*DEBUG-end*/
. Pozostałe znaki spacji zostaną usunięte przez minimizer.Innym sposobem radzenia sobie z tym problemem jest „odgięcie” obiektu konsoli, gdy nie jest on zdefiniowany, aby w kontekstach, które nie mają konsoli, nie są wyrzucane żadne błędy, tj.
if (!window.console) { var noOp = function(){}; // no-op function console = { log: noOp, warn: noOp, error: noOp } }
masz pomysł ... istnieje wiele funkcji zdefiniowanych w różnych implementacjach konsoli, więc można je wszystkie, czy tylko te, które używają skrótową (np jeśli tylko kiedykolwiek używać
console.log
i nigdy nie używaneconsole.profile
,console.time
etc ...)Jest to dla mnie lepsza alternatywa w rozwoju niż dodawanie warunkowych przed każdym połączeniem lub ich niestosowanie.
zobacz także: Czy pozostawienie wywołań „console.log ()” w swoim produkcie w kodzie JavaScript to zły pomysł?
źródło
$.noop
.UglifyJS2
Jeśli używasz tego minifier, możesz ustawić
drop_console
opcję :Dlatego sugerowałbym pozostawienie
console.log
połączeń, ponieważ dotyczą one najtrudniejszej części kodu.źródło
drop_console
sięfalse
, obserwować je i schować je ponownie.Jeśli minifikacja jest częścią procesu kompilacji, możesz jej użyć do usunięcia kodu debugowania, jak wyjaśniono tutaj w przypadku kompilatora zamknięcia Google: Wyklucz debugowany kod JavaScript podczas minifikacji
if (DEBUG) { console.log("Won't be logged if compiled with --define='DEBUG=false'") }
Jeśli kompilujesz z zaawansowanymi optymalizacjami, ten kod zostanie nawet zidentyfikowany jako martwy i całkowicie usunięty
źródło
Tak. console.log zgłosi wyjątek w przeglądarkach, które go nie obsługują (obiekt konsoli nie zostanie znaleziony).
źródło
Generalnie tak, ujawnianie komunikatów dziennika w kodzie produkcyjnym nie jest dobrym pomysłem.
Najlepiej byłoby usunąć takie komunikaty dziennika za pomocą skryptu kompilacji przed wdrożeniem; ale wiele (większość) osób nie korzysta z procesu kompilacji (w tym ja).
Oto krótki fragment kodu, którego ostatnio używałem, aby rozwiązać ten dylemat. Naprawia błędy spowodowane przez niezdefiniowane
console
w starym IE, a także wyłącza logowanie w "trybie deweloperskim".// 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); }
Jestem prawie pewien, że wziąłem wiele z powyższego
addConsoleNoOp
f'n z innej odpowiedzi na SO, ale nie mogę teraz znaleźć. Jeśli znajdę, dodam odniesienie później.edytuj: Nie ten post, o którym myślałem, ale tutaj jest podobne podejście: https://github.com/paulmillr/console-polyfill/blob/master/index.js
źródło
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; })();
Stosowanie:
var debugMode=true; var appLogger = new AppLogger(debugMode); appLogger.conlog('test');
źródło
Tak, dobrą praktyką jest używanie go
console.log
do celów debugowania javascript, ale należy go usunąć z serwera produkcyjnego lub w razie potrzeby dodać na serwerze produkcyjnym z kilkoma kluczowymi kwestiami, które należy wziąć pod uwagę:**var isDebugEnabled="Get boolean value from Configuration file to check whether debug is enabled or not".** if (window.console && isDebugEnabled) { console.log("Debug Message"); }
Powyższy blok kodu musi być używany wszędzie do logowania, aby najpierw sprawdzić, czy konsola jest obsługiwana przez bieżącą przeglądarkę i czy debugowanie jest włączone, czy nie.
źródło
TL; DR
Pomysł: Rejestrowanie obiektów wyklucza ich zbieranie śmieci.
Detale
console.log
te obiekty są dostępne przez odniesienie z konsoli DevTools. Możesz to sprawdzić, logując obiekt, mutując go i stwierdzając, że stare komunikaty odzwierciedlają późniejsze zmiany obiektu.To tylko pomysł: zaznaczyłem punkty 1 i 2, ale nie 3.
Rozwiązanie
Jeśli chcesz przechowywać dzienniki ze względu na rozwiązywanie problemów po stronie klienta lub w innych celach:
['log', 'warn', 'error'].forEach( (meth) => { const _meth = window.console[meth].bind(console); window.console[meth] = function(...args) { _meth(...args.map((arg) => '' + arg)) } });
źródło
Zasadniczo nadpisuję funkcję console.log tą, która ma wiedzę o tym, gdzie kod jest uruchamiany. Dzięki temu mogę nadal korzystać z console.log, jak zawsze. Automatycznie wie, że jestem w trybie dev / qa lub w produkcji. Jest też sposób, aby to wymusić. Oto działające skrzypce. http://jsfiddle.net/bsurela/Zneek/
Oto fragment, ponieważ przepełnienie stosu jest zastraszane przez osoby wysyłające plik 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); } },
źródło
Wiem, że to dość stare pytanie i od jakiegoś czasu nie było zbyt aktywne. Chciałem tylko dodać moje rozwiązanie, które wymyśliłem, a które wydaje mi się całkiem dobre.
/** * 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; } } }
Następnie zazwyczaj tworzę funkcję w moich skryptach, takich jak ten lub możesz udostępnić ją w globalnym skrypcie:
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!'); } } }
A potem używam tego zamiast console.log w ten sposób:
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); }
źródło
Jeśli przepływ pracy jest wykonywany przy użyciu odpowiednich narzędzi, takich jak
parcel
/,webpack
to już nie jest ból głowy, ponieważ wraz z upuszczaniemproduction
kompilacjiconsole.log
. Jeszcze kilka lat wcześniej zGulp
/Grunt
to również mogło zostać zautomatyzowane.Wiele współczesnych ram, takich jak
Angular
,React
,Svelte
,Vue.js
pochodzą z tej instalacji out-of-the-box. Zasadniczo nie musisz nic robić, o ile wdrożysz poprawną kompilację, tj.production
Taką,development
której nadal nie będziesz miećconsole.log
.źródło