35

Should you remove the console.log() calls before deploying a React Native app to the stores? Are there some performance or other issues that exist if the console.log() calls are kept in the code?

Is there a way to remove the logs with some task runner (in a similar fashion to web-related task runners like Grunt or Gulp)? We still want them during our development/debugging/testing phase but not on production.

Nimantha
  • 6,405
  • 6
  • 28
  • 69
RRikesh
  • 14,112
  • 5
  • 49
  • 70

7 Answers7

79

Well, you can always do something like:

if (!__DEV__) {
  console.log = () => {};
}

So every console.log would be invalidated as soon as __DEV__ is not true.

Lucas Bento
  • 1,212
  • 4
  • 17
  • 17
  • 4
    This is cleaner, and should be the accepted answer. Just make sure these lines run before everything else. – csotiriou Apr 04 '17 at 12:58
  • 1
    @csotiriou: so would that mean at the top of App.js before all imports? – raarts Jun 30 '17 at 08:55
  • 1
    @raarts yes. However I have the feeling that react native is doing this automatically, but only for the default release builds. In Xcode, even if I add a custom release build, it doesn't hide the logs. Still trying to find an alternative though. – csotiriou Jul 01 '17 at 19:50
  • Does this also work in React JS? Is the `__DEV__` constant documented somewhere? – kojow7 May 30 '18 at 02:23
  • You can provide an environment variable to define whether the app in development or production and do the same as the answer indicates. If you use webpack I believe you can use `process.env.NODE_ENV`. – Lucas Bento May 30 '18 at 12:18
  • 2
    I like this answer. It's really clean, however facebook's docs suggest using babel-plugin-transform-remove-console as pointed out by @adam. Has anyone tried this ? and does it really work ? https://facebook.github.io/react-native/docs/performance.html#using-consolelog-statements – kodeCoala Jul 06 '18 at 02:19
  • 1
    This answer is two years-old, it was correct for the time of writing as well for nowadays, @adambene's reply does not make this incorrect. – Lucas Bento Sep 17 '19 at 12:27
  • If you go for this solution, i think console.warn, console.error and etc need to be included as well. I was also thinking the use of Babel transpiler is actually more optimized than the invalidation process at run time? – luke77 May 16 '20 at 20:08
  • 1
    @kodeCoala yes I have used it in my code base, it's easy to use and gets the job done well! – Baseless Jun 22 '23 at 04:55
70

Babel transpiler can remove console statements for you with the following plugin:

npm i babel-plugin-transform-remove-console --save-dev

Edit .babelrc:

{
  "env": {
    "production": {
      "plugins": ["transform-remove-console"]
    }
  }
}

And console statements are stripped out of your code.

source: https://hashnode.com/post/remove-consolelog-statements-in-production-in-react-react-native-apps-cj2rx8yj7003s2253er5a9ovw

adambene
  • 1,143
  • 9
  • 16
  • 6
    Better to use -D rather than --save to save it to devDependencies. – Alexander Danilov Oct 23 '17 at 07:16
  • 2
    I tried this but couldnt find .babelrc file in my directory – mad_greasemonkey Feb 19 '18 at 09:37
  • 2
    @JayakrishnanMenon then obviously you have to create .babelrc, and setup babel transpiler – adambene Feb 20 '18 at 09:53
  • 3
    I am kind of a noob in this. Can you explain a bit more on that? – mad_greasemonkey Feb 20 '18 at 14:31
  • Going through same situation. Can you explain in detail? – HungrySoul Mar 16 '18 at 11:07
  • @AlexanderDanilov Can you explain that a bit further? Shouldn't it only remove them console.log statements in production? Doesn't -D (devDependencies) mean that you are run in development mode and not production mode. Please excuse my ignorance. – kojow7 May 30 '18 at 02:33
  • @kojow7 babel plug-ins should be used only on dev machine and not included into apps bundle. – Alexander Danilov May 31 '18 at 07:09
  • before adding above code my .babelrc having "presets": ["react-native"], should I keep including the line? at android build i am getting this warning message "You or one of the Babel plugins you are using are using Flow declarations as bindings. Support for this will be removed in version 7. To find out the caller, grep for this message and change it to a `console.trace()`" – Amit Bravo Sep 17 '18 at 10:14
  • 6
    How do these environments work? How does react-native know it is a production build? Is there a staging and production environment as well? – Thomas Stubbe Sep 26 '18 at 09:21
  • is this work when we create build using Xcode or android studio – Prajapati Jigar May 01 '20 at 08:36
  • Do we need this with the current React Native process ? Since React Native automatically use babel to minify our code, do we still need to add this babel config ? And also by doind this, does it removed the default minifying of React Native ? – Julien Pepe Feb 05 '23 at 18:21
18

believe best practice is to wrap your debug code in statements such as...

    if(__DEV__){
        console.log();
    }

This way, it only runs when you're running within the packager or emulator. More info here... https://facebook.github.io/react-native/docs/performance#using-consolelog-statements

This would also work...

__DEV__ && console.log('logged only in __DEV__');
Chris Geirman
  • 9,474
  • 5
  • 37
  • 70
17

I know this question has already been answered, but just wanted to add my own two-bits. Returning null instead of {} is marginally faster since we don't need to create and allocate an empty object in memory.

if (!__DEV__)
{
   console.log = () => null
}

This is obviously extremely minimal but you can see the results below

// return empty object
console.log = () => {}
console.time()
for (var i=0; i<1000000; i++) console.log()
console.timeEnd()

// returning null
console.log = () => null
console.time()
for (var i=0; i<1000000; i++) console.log()
console.timeEnd()

Although it is more pronounced when tested elsewhere:

empty console function

Honestly, in the real world this probably will have no significant benefit just thought I would share.

Asleepace
  • 3,466
  • 2
  • 23
  • 36
  • 1
    The {} in () => {} is an empty function body, not an object. Returning a object would be () => ({}). Also, if you switch the order of the performance tests to see, the first one will show as taking longer. – angleKH Aug 07 '21 at 20:30
8

I tried it using babel-plugin-transform-remove-console but the above solutions didn't work for me .

If someone's also trying to do it using babel-plugin-transform-remove-console can use this one.

npm i babel-plugin-transform-remove-console --save-dev

Edit babel.config.js

module.exports = (api) => {
  const babelEnv = api.env();
  const plugins = [];
  if (babelEnv !== 'development') {
    plugins.push(['transform-remove-console']);
  }
  return {
    presets: ['module:metro-react-native-babel-preset'],
    plugins,
  };
};


sakshya73
  • 5,570
  • 5
  • 22
  • 41
3

I have found the following to be a good option as there is no need to log even if __DEV__ === true, if you are not also remote debugging.

In fact I have found certain versions of RN/JavaScriptCore/etc to come to a near halt when logging (even just strings) which is not the case with Chrome's V8 engine.

// only true if remote debugging
const debuggingIsEnabled = (typeof atob !== 'undefined');

if (!debuggingIsEnabled) {
    console.log = () => {};
}

Check if in remote JS debugging is enabled

James Trickey
  • 1,322
  • 13
  • 21
1

Using Sentry for tracking exceptions automatically disables console.log in production, but also uses it for tracking logs from device. So you can see latest logs in sentry exception details (breadcrumbs).

Alexander Danilov
  • 3,038
  • 1
  • 30
  • 35
  • Hi, can you link to a document of sentry that show how to disable console.log? Or do they do that automatically without the need of any config? (I can't seem to find info about this) – huong Jul 18 '18 at 03:50
  • @friedegg-bacon-sandwich they do that automatically. – Alexander Danilov Jul 19 '18 at 18:42
  • Great! :) But do you have a link to some docs to confirm this? I can't seem to find it anywhere – TamRock Sep 24 '18 at 12:26
  • @TamRock docs are quite bad :) but i found this https://blog.sentry.io/2017/01/19/node-breadcrumbs#getting-started for nodejs. I guess they copied this behavior to RN. – Alexander Danilov Sep 24 '18 at 13:14
  • Looking at Sentry's code, I don't think that `console.log()` statements are removed. Here's what I'm referencing: https://github.com/getsentry/sentry-javascript/blob/master/packages/integrations/src/captureconsole.ts – Alex W Jun 24 '21 at 19:36