10

I'd like to make my JS code production ready by stripping out all console.log("blah blah") debugging statements. I'm confused by this popular SO answer (code below) on how to do this using Google's closure compiler, a popular JS minifier/compiler.

/** @const */
var LOG = false;
...
LOG && log('hello world !'); // compiler will remove this line
...

//this will even work with `SIMPLE_OPTIMALIZATIONS` and no `--define=` is necessary !

Two questions:

  1. Multiples files: How does the above code work with multiple files (basic example below)? It has to be in a closure, right? Doesn't this then mean you have to put this code on each page? Also, doesn't it also then mean you have to change all the variables you want to be global from var foo='bar' to var window.foo='bar'; inside these closures on each page?

  2. Minor issue: Shouldn't it be console.log('...') rather than log('...') because log() gives an error? Am I missing something obvious here?

<script src='/assets/js/file1.js'></script> <script src='/assets/js/file2.js'></script>

contents of file1.js:

var foo='bar';
console.log("foo"+foo);

contents of file2.js

var baz='bazzy';
console.log("baz"+baz);
Community
  • 1
  • 1
tim peterson
  • 23,653
  • 59
  • 177
  • 299
  • `log` is a generalized logging function which could simply be a wrapper for `console.log` or could provide some other type of logging. It was simply used for demonstration. The definition is left as an exercise to the reader. – Chad Killingsworth Sep 16 '13 at 21:31
  • @ChadKillingsworth thanks, I didn't know whether it was an exercise or something I hadn't learned yet about JS. – tim peterson Sep 16 '13 at 21:37

3 Answers3

2

If you have your code split up into multiple files, I would think you'd want to have a build process that joins them into one immediately invoked function. Then your var LOG = false; can just be included once at the top.

If by "each page", you mean that you have separate JavaScript files per page that aren't meant to be joined together, then yes, you'd need to have that code at the top of each, but then you're also not taking as much advantage of Closure Compiler.

Regarding globals, yes, you'd need to use window when setting, though I would hope you're defining only one global.

The use of log() implies that someone defined a log() function so that it's less verbose.

function log() {
    return console.log.apply(console, arguments);
}
user2736012
  • 3,543
  • 16
  • 13
  • thanks! I've now better explained what I mean by "multiple files" in my question. Please see the edits. – tim peterson Sep 16 '13 at 21:35
  • -@user2736012 can you provide a basic example of "a build process that joins them into one immediately invoked function"? I'm not quite sure what you mean by that. Closure compiler is making one big JS file from my file1.js, file2.js, jquery.js, etc. – tim peterson Sep 16 '13 at 21:42
  • Some server-side code to facilitate an automated process of taking your individual files, joining them together into one file, running desired processes against the file (like Closure Compiler), and outputting the result to a new file to be included with your project. – user2736012 Sep 16 '13 at 21:59
  • ok thanks now that's clear. last question: why only one global? just cause good code practice? prevent name collisions? other reasons? – tim peterson Sep 16 '13 at 22:06
  • 1
    @timpeterson: Yeah, it's considered good practice to minimize the number of globals created mainly for the purpose you described... name collisions. – user2736012 Sep 16 '13 at 22:15
  • In 2019 Google Closure Compiler still can not automatically remove all `console.*`? – Vitaly Zdanevich Apr 15 '19 at 19:03
0

I think you don't understand the answer from your link. Author suggests you to create a new variable

var LOG = false;

then you simply write LOG && __code__ ; ( coressponds to if(LOG) __code__ ; ) and the code after && will not be processed, because of partial evaluation of boolean expressions. It will be processed, after you set LOG to true. The variable is usually called a "switch" or "flag".

By the way, Closure Compiler may edit your code, but that code must behave the same after "compilation" as before it. That is the main principle of all these minifiers and optimizers (they must not convert your Quick Sort into GTA 5). So don't use Closure Compiler to make your code work differently (it is not possible, if it is - they have a bug in it!).

Ivan Kuckir
  • 2,327
  • 3
  • 27
  • 46
  • -@IvanKuckir thanks. "I think you don't understand the answer from your link". Yes that is why I asked the question. :) – tim peterson Sep 16 '13 at 21:37
0

Taking the OP's example, if you don't want to modify file1.js you can compile it with an additional file (noconsole.js) containing:

console.log = console.debug = console.info = function(){};

Such as:

google-closure-compiler --js noconsole.js file1.js --js_output_file file1.out.js

As explained in my previous answer.

Nagev
  • 10,835
  • 4
  • 58
  • 69