Tôi có nên xóa console.log khỏi mã sản xuất không?


86

Tôi hiện có câu lệnh JS này ở khắp mọi nơi trong mã của mình:

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

Tôi đang tự hỏi liệu điều này có tốn kém hay có bất kỳ tác dụng phụ tiêu cực nào trong quá trình sản xuất hay không.

Tôi có rảnh để đăng nhập phía máy khách hay nên bắt đầu?

CHỈNH SỬA: Cuối cùng, tôi cho rằng lập luận tốt nhất mà tôi (và bất kỳ ai khác?) Có thể đưa ra là có một lượng dữ liệu bổ sung có thể không đáng kể được chuyển giữa máy chủ và máy khách bằng cách để lại thông báo đăng nhập. Nếu mã sản xuất phải được tối ưu hóa hoàn toàn, việc ghi nhật ký sẽ phải được xóa để giảm kích thước của javascript được gửi đến máy khách.


Câu trả lời:


41

Bạn không nên thêm các công cụ phát triển vào một trang sản xuất.

Để trả lời câu hỏi khác: Mã không được có tác dụng phụ tiêu cực:

  • window.consolesẽ đánh giá thành false nếu consolekhông được xác định
  • console.log("Foo")sẽ in thông báo tới bảng điều khiển khi nó được xác định (miễn là trang không bị console.logmột chức năng nào ghi đè lên ).

43
Tôi đồng ý với bạn về nguyên tắc. Nhưng, tôi nghĩ rằng tất cả chúng ta đều đồng ý rằng việc triển khai ghi nhật ký không kích hoạt ngoại trừ trong chế độ gỡ lỗi là cần thiết cho mã phía máy chủ chất lượng. Không ai duyệt và xóa nhật ký của họ cho bản phát hành sản xuất - chương trình xác định mức độ ghi nhật ký là cần thiết và phản ứng tương ứng. Tôi hy vọng có điều gì đó tương tự như điều này cho lập trình phía máy khách ... thậm chí chỉ cần đặt một biến "isDebug", nếu cần. Tại sao tôi muốn tạo gánh nặng cho nhà phát triển tiếp theo bằng cách yêu cầu quay lại và thêm lại ghi nhật ký cho các khu vực có vấn đề trong tương lai?
Sean Anderson

11
Tồi tàn như thế nào? Tôi lập luận rằng việc nói bảng điều khiển dành cho nhà phát triển là một phần của trang web sản xuất giống như nói rằng các tệp nhật ký là một phần của ứng dụng. Có, cả hai đều được tạo bằng mã, nhưng cần phải hiểu một số mức độ rằng các bản ghi phải được để ở đâu đó. Tuy nhiên, các câu lệnh bên trong nhật ký có thân thiện với người dùng hay không là một vấn đề khác.
Sean Anderson

4
Làm thế nào một người sẽ tự động loại bỏ mã gỡ lỗi trước khi thu nhỏ? Có rất nhiều biểu mẫu mà thông báo nhật ký phía máy khách có thể thực hiện.
Sean Anderson

6
Bạn có thể đánh dấu mọi đoạn mã gỡ lỗi, ví dụ bằng cách thêm tiền tố / hậu tố một dòng mã gỡ lỗi bằng một nhận xét. Ví dụ: /*DEBUG:start*/console.log("Foo");/*DEBUG:end*/. Sau đó, sử dụng RegExp để loại bỏ tất cả các lần xuất hiện của /*DENUG-start*/[\S\s]*?/*DEBUG-end*/. Các ký tự khoảng trắng còn lại sẽ bị xóa bằng trình thu nhỏ.
Rob W

3
Trừ khi câu trả lời này nói TẠI SAO bạn không nên làm điều đó, nó thực sự không hữu ích. Chúng ta chỉ nên chấp nhận một cách mù quáng rằng nó tồi tệ mà không có bằng chứng hay lý do?
ESR

48

Một cách khác để giải quyết vấn đề này là 'khai' ra đối tượng console khi nó không được xác định để không có lỗi nào được đưa ra trong các ngữ cảnh không có console, tức là

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

bạn có ý tưởng ... có rất nhiều chức năng được xác định trên các triển khai khác nhau của bảng điều khiển, vì vậy bạn có thể khai thác tất cả hoặc chỉ những chức năng bạn sử dụng (ví dụ: nếu bạn chỉ sử dụng console.logvà chưa bao giờ sử dụng console.profile, console.timev.v.)

Đối với tôi, đây là một sự thay thế tốt hơn trong quá trình phát triển so với việc thêm các điều kiện vào trước mỗi cuộc gọi, hoặc không sử dụng chúng.

xem thêm: Có phải là một ý tưởng tồi nếu để lệnh gọi "console.log ()" trong mã JavaScript sản phẩm của bạn?


6
Ý tưởng tốt. Chỉ cần một số bản sửa lỗi cần thiết. Trình gỡ lỗi Visual Studio JS ném vào console.log = noOp () đầu tiên vì bản thân đối tượng console không được định nghĩa. Tôi đã làm như thế này: console = {log: noOp, warning: noOp, error: noOp}. Cũng lưu ý rằng bạn không muốn đặt () sau noOp - bạn muốn gán chính hàm chứ không phải giá trị trả về của nó. Đã thử nghiệm trên trình gỡ lỗi Visual Studio JS và IE9 - bây giờ nó hoạt động tốt.
JustAMartin

3
FYI, nếu bạn đang sử dụng jQuery, họ cung cấp một chức năng noop: $.noop.
nghiền nát

28

UglifyJS2

Nếu bạn đang sử dụng bộ thu nhỏ này, bạn có thể đặt drop_consoletùy chọn :

Chuyển true để hủy các lệnh gọi đến bảng điều khiển. * Chức năng

Vì vậy, tôi khuyên bạn nên để lại console.logcác cuộc gọi vì chúng là một phần khó nhất của cơ sở mã.


3
Nếu bạn đang sử dụng gruntuglify , tùy chọn tương tự cũng có sẵn (có vẻ như uglify dựa trên UglifyJS2): github.com/gruntjs/…
Tilt

1
Câu hỏi là "tôi nên", không phải "làm thế nào để tôi".
ESR

Bạn nên để console.errors vào. Nếu ai đó trong quá trình sản xuất gặp sự cố, thì bạn có thể dễ dàng chẩn đoán nó. Đừng tước console.errors!
Oliver Watkins

Nếu sẽ có một nhu cầu cho họ sau đó bạn chỉ có thể thiết lập drop_consoleđể false, quan sát họ và ẩn chúng một lần nữa.
terales

16

Nếu thu nhỏ là một phần trong quá trình xây dựng của bạn, bạn có thể sử dụng nó để loại bỏ mã gỡ lỗi, như được giải thích ở đây với trình biên dịch đóng của Google: Loại trừ mã JavaScript gỡ lỗi trong quá trình rút gọn

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

Nếu bạn biên dịch với các tối ưu hóa nâng cao, mã này thậm chí sẽ được xác định là đã chết và bị xóa hoàn toàn


1
Cảm ơn bạn! Tôi vẫn đang tìm kiếm điều này. :)
Sean Anderson

5

Đúng. console.log sẽ đưa ra một ngoại lệ trong các trình duyệt không hỗ trợ nó (sẽ không tìm thấy đối tượng console).


không phải với đánh giá ngắn mạch của anh ấy, miễn là cửa sổ được xác định
Joe

1
Mặc dù tôi đã bỏ lỡ nó trong câu trả lời đầu tiên của mình, nhưng cũng nên kiểm tra console.log.
MK_Dev

Tôi hầu như chỉ thực hiện window.console để tránh rắc rối với IE. Tôi vẫn chưa gặp phải tình huống mà nhật ký bị ghi đè ngoài ý muốn, nhưng tôi chắc rằng điều đó có thể xảy ra.
Sean Anderson

@MK_Dev Cụ thể là những trình duyệt nào?
goodpixels

Đó là năm 2019. Tôi nghi ngờ có bất kỳ trình duyệt nào không hỗ trợ bảng điều khiển.
Oliver Watkins

5

Nói chung là có, không phải là một ý tưởng tuyệt vời nếu để lộ thông báo nhật ký trong mã sản xuất của bạn.

Tốt nhất, bạn nên xóa các thông báo nhật ký như vậy bằng một tập lệnh xây dựng trước khi triển khai; nhưng nhiều người (hầu hết) không sử dụng một quy trình xây dựng (bao gồm cả tôi).

Đây là một đoạn mã ngắn mà tôi đã sử dụng gần đây để giải quyết tình huống khó xử này. Nó sửa các lỗi do không xác định consoletrong IE cũ, cũng như vô hiệu hóa ghi nhật ký nếu ở trong "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);
}

Tôi khá chắc chắn rằng tôi đã lấy phần lớn các addConsoleNoOpcâu hỏi trên từ một câu trả lời khác trên SO, nhưng không thể tìm thấy ngay bây giờ. Tôi sẽ thêm một tài liệu tham khảo sau nếu tôi tìm thấy nó.

chỉnh sửa: Không phải bài đăng tôi đang nghĩ đến, nhưng đây là một cách tiếp cận tương tự: 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;
})();

Sử dụng:

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

1

Có, phương pháp hay để sử dụng console.logcho mục đích gỡ lỗi javascript, nhưng nó cần được xóa khỏi máy chủ sản xuất hoặc nếu cần, có thể thêm vào máy chủ sản xuất với một số điểm chính cần được xem xét:

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

Khối mã trên phải được sử dụng ở mọi nơi để ghi nhật ký để trước tiên xác minh xem bảng điều khiển có được hỗ trợ cho trình duyệt hiện tại hay không và gỡ lỗi có được bật hay không.

isDebugEnabled phải được đặt là true hoặc false dựa trên môi trường của chúng ta.


1

TL; DR

Ý tưởng: Các đối tượng ghi nhật ký ngăn không cho chúng bị Thu gom rác.

Chi tiết

  1. Nếu bạn chuyển các đối tượng vào console.logthì các đối tượng này có thể truy cập được bằng cách tham chiếu từ bảng điều khiển của DevTools. Bạn có thể kiểm tra nó bằng cách ghi lại đối tượng, thay đổi nó và nhận thấy rằng các thư cũ phản ánh những thay đổi sau này của đối tượng.
  2. Nếu nhật ký quá dài, các tin nhắn cũ sẽ bị xóa trong Chrome.
  3. Nếu nhật ký ngắn thì các thư cũ sẽ không bị xóa, nếu các thư này tham chiếu đến các đối tượng thì các đối tượng này không được Thu thập rác.

Nó chỉ là một ý tưởng: Tôi đã kiểm tra điểm 1 và 2 nhưng không phải 3.

Giải pháp

Nếu bạn muốn giữ nhật ký để xử lý sự cố phía máy khách hoặc các nhu cầu khác thì:

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

0

Về cơ bản, tôi ghi đè hàm console.log bằng một hàm có kiến ​​thức về nơi mã đang được chạy. Vì vậy, tôi có thể tiếp tục sử dụng console.log như tôi thường làm. Nó tự động biết rằng tôi đang ở chế độ dev / qa hoặc đang sản xuất. Cũng có một cách để buộc nó. Đây là một fiddle đang hoạt động. http://jsfiddle.net/bsurela/Zneek/

Đây là đoạn mã vì tràn ngăn xếp được hiểu bởi những người đăng 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

Tôi biết đây là một câu hỏi khá cũ và đã không có nhiều hoạt động trong một thời gian. Tôi chỉ muốn thêm giải pháp của mình mà tôi đã nghĩ ra có vẻ hoạt động khá tốt đối với tôi.

    /**
     * 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;
            }
        }
    }

Sau đó, tôi thường tạo một hàm trong các tập lệnh của mình như thế này hoặc bạn có thể cung cấp nó trong một tập lệnh chung:

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!');
        }           
    }   
}

Và sau đó tôi chỉ sử dụng nó thay vì console.log như thế này:

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

Nếu quy trình làm việc được thực hiện bằng cách sử dụng các công cụ phù hợp như parcel/ webpackthì nó không còn là vấn đề đau đầu nữa, bởi vì bản productiondựng console.logđang bị loại bỏ. Thậm chí vài năm trước đó với Gulp/ Gruntnó cũng có thể được tự động hóa.

Nhiều người trong số các khuôn khổ hiện đại như Angular, React, Svelte, Vue.jsđi kèm với thiết lập mà out-of-the-box. Về cơ bản, bạn không phải làm bất cứ điều gì, miễn là bạn triển khai đúng bản dựng, tức là productionmột bản, không phải bản dựng developmentvẫn sẽ có console.log.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.