Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need option to remove console.* #28

Closed
Tazeg opened this issue Feb 20, 2020 · 10 comments
Closed

Need option to remove console.* #28

Tazeg opened this issue Feb 20, 2020 · 10 comments

Comments

@Tazeg
Copy link

Tazeg commented Feb 20, 2020

No description provided.

@evanw
Copy link
Owner

evanw commented Feb 20, 2020

This is possible today with the ---define option:

DEBUG && console.log('debug-only log');

With a debug build using esbuild --define:DEBUG=true, the log is preserved:

console.log('debug-only log');

With a release build using esbuild --define:DEBUG=false --minify, the log is completely removed.

I will consider adding a feature lets you remove calls to global functions. It looks like other bundlers handle this by marking certain functions as "pure", which means they don't have any side effects. Then the optimizer will remove them. Any side effects that the arguments have will still happen, however.

@Tazeg
Copy link
Author

Tazeg commented Feb 20, 2020

So it means i have to update my code to add a DEBUG test before each console.* ?
Terser can do the job with : compress: { drop_console: true } whithout changing my code.
So yes, please consider adding a feature.

@alystair
Copy link

alystair commented May 8, 2020

@evanw must it be that precise syntax or do you allow for something like if (DEBUG) ... and or more 'complex' statements such as if (DEBUG && Foo ) ...?

@evanw
Copy link
Owner

evanw commented May 9, 2020

Yes, they all work.

DEBUG && console.log(1)
if (DEBUG) console.log(2)
if (DEBUG && Foo) console.log(3)

All three statements above will be removed with --define:DEBUG=false --minify and will become this with --define:DEBUG=true --minify:

console.log(1), console.log(2), Foo && console.log(3);

What happens is that DEFINE is replaced with false and then the compiler's dead-code elimination rules kick in.

@alystair
Copy link

alystair commented May 9, 2020

That's... that's so simple and brilliant! General feature flagging... this is legitimately inspiring me right now.

It would also eliminate optional chains like WIP?.foo.funct(); with --define:WIP=false right?

@evanw
Copy link
Owner

evanw commented May 9, 2020

Yes, you could also do that. I suppose that means you could write console?.log(something) and then do --define:console=null to remove them. Although that would mean any time you forget the ? and write console.log(something) instead, that would be transformed to null.log(something) which would crash at run time, so that's probably not a good idea.

I just checked what esbuild does and it looks like esbuild's dead code elimination for optional chains only works if you set --target=es2019 or below, since that's when it's transformed for older browsers. I'll fix that so dead code elimination works with --target=es2020 and up too.

@alystair
Copy link

alystair commented Jun 7, 2020

Evan just a quick follow up - what happens when there's a following 'else' statement? For example: if (DEBUG) { ... } else { ... }

@evanw
Copy link
Owner

evanw commented Jun 7, 2020

Constructs such as if (true) a; else b; and true ? a : b become a and constructs such as if (false) a; else b; and false ? a : b become b.

@evanw evanw closed this as completed in 3d39e8c Jul 6, 2020
@evanw
Copy link
Owner

evanw commented Jul 6, 2020

With version 0.5.22 you can now do --pure:console.log and esbuild will remove calls to console.log if --minify is present (specifically --minify-syntax). As I mentioned above, any arguments to the function call with side effects will still be evaluated for correctness.

@stephband
Copy link

stephband commented Oct 10, 2021

Hello. I am puzzled as to why the minifier is not stripping this code:

const DEBUG = window.DEBUG;

if (DEBUG) {
    console.log('Strip me');
}

when built with the options:

{
    define: { 'window.DEBUG': false },
    minify:    true
}

The odd thing is those same options will happily strip this:

if (window.DEBUG) {
    console.log('Strip me');
}

The reason I want to do this is I like to write code that will run in the browser before and after building, and it is useful to be able to do something like this at the top of a file:

const DEBUG = window.DEBUG !== false;

Which allows pre-build debug code to run where window.DEBUG has not been set. I could put that into every condition...

if (window.DEBUG !== false) {
    console.log('Strip me');
}

... but it would be nice not to have to do that everywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants