Does console.debug() affect react native performance in release mode - reactjs

I know that console.log() will affect react native's pref under release mode, this is stated very clear in the docs, but what about console.debug() and console.warn()?
Otherwise what's the best way to print debug message and not having to take all of them out every time we go into release? Since we will need these message in dev mode again.

If you check the documentation, there are some instructions on how to use the babel plugin to automatically remove all the console.* calls in the release builds.
According to it [1], you just need to install the plugin:
1)
npm i babel-plugin-transform-remove-console --save
2) Add this in your .babelrc file:
{
"env": {
"production": {
"plugins": ["transform-remove-console"]
}
}
}
1 - https://facebook.github.io/react-native/docs/performance.html#using-console-log-statements

There are webpack plugins that are designed to remove specific types of console statements, depending on how you configure them, so that you can, for example, remove only console.debug statements but the last time I tried, I didn't have much luck.
If you are building a React JS app with a recent version of React, for example 15.x, that was created with create-react-app and you eject it with npm run eject, you'll have two separate webpack configurations. You can modify the production configuration (/config/webpack.config.prod.js) and remove all console statement from your production build by modifying the existing UglifyJsPlugin configuration in the plugins section so that it looks something like this:
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
// Disabled because of an issue with Uglify breaking seemingly valid code:
// https://github.com/facebookincubator/create-react-app/issues/2376
// Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
// Drop console statements
drop_console: true, // <--- ADD THIS
},
output: {
comments: false,
},
sourceMap: true,
}),
That's all you should need to do... but again, this will remove all console statements, not just console.debug

Related

angularjs-route not loading with angular --prod flag (angular-cli)

Context: I'm migrating from ngJs to ng10, the application runs normally when I not use the --prod flag
The thing is: when i use --prod flag the routes doesn't load and i am super clueless why not.
The only difference I see printing the "next" attribute on the $routeChangeStart is that the "next" object on --prod mode doesnt have an attribute called "locals"
2nd. weird thing: the $routeChangeStart is triggered when i change the URL on the URL bar as it should be, cus the $routeChangeStart is printed every time i change the URL
3rd. weird thing: for testing purposes i change templateUrl in the config for a template:'<div>Arcade PvP silly text</div>' and it doesnt load either, and as far i see, the controller of any view never triggers.
Pls help.
Angular-CLI 10.0.5
Angular 1.7.6 bootstraped over Angular 10.0.6
Okay, I manage to understand more deeply the reasons of this behavior and manage to make a workaround, gonna documentate it here:
This is an application made in AngularJS (1.7.x) bootstrapped over Angular 10.0.5
Deploying the application with ng serve --configuration=dev makes it work as expected after the normal long process of configure the different index.ts and convert everything from *.js to *.ts
The reason of the issue is located in the angular.json:
{
"projects":{
[project_name]:{
"architect":{
"build":{
"configurations":{
"production":{
...
"optimization":true <------- THIS
}
...
}}}}}}
The optimization flag effectively makes the bundle very lightweight and ng build --prod compiles normally. But as I mention in the question, the problem occurs at runtime: the routes "load" but the HTML never renders for any route configured, therefore ANY of the controllers either runs.
In deep investigation, the optimization flag tells the angular-cli webpack to run the minification over the JS, and by past experience, AngularJS seems to be tricky to receive the minifications/uglify processing all due to the mangle process, my problem is one of the reasons why.
Angular-CLI's Webpack runs TerserPlugin to make the minification and I need to configurate it to avoid using mangle, Angular now allows to use a custom webpack configuration file to add rules, this is achieved like this:
create a new file in the project base folder, let's say named custom-webpack.config.js
Reference this file in the angular.json build:
{
"projects":{
[project_name]:{
"architect":{
"build":{
"builder":"#angular-builders/custom-webpack:browser",
"options":{
"customWebpackConfig": {
"path": "./custom-webpack.config.js"
},
...
}
}}}}}}
In the file, let's do this:
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: true,
terserOptions: {
mangle: false,
ie8:false,
safari10:false
}
}),
],
}
}
And voila! The minification occurs, but not the mangle, the application will reduce it's bundle size as expected (mostly) and the angular-route will work normally.

Unexpected character '#' (1:0) on Gatsby after installing package

Basically I am getting this list of errors after installing react-awesome-query-builder package on a brand new installed Gatsby environment.
The examples to this solution, point to add some configuration to the webpack.config.js, but on Gatsby not sure where I can add the fixes. If someone can point me to the right direction.
While there is a way to add custom webpack config settings in Gatsby, this issue might be solvable by adding Gatsby packages for less and ant design (gatsby-plugin-antd, and gatsby-plugin-less).
npm install --save antd gatsby-plugin-antd less gatsby-plugin-less
You will also need to add them into your gatsby-config.js file:
plugins: [
{
resolve: "gatsby-plugin-antd",
options: {
style: true,
},
},
{
resolve: "gatsby-plugin-less",
options: {
javascriptEnabled: true,
},
}
]
Each of them have additional configurations you can add in. For gatsby-plugin-antd, you'll want style set to true since it is using less.
For the gatsby-plugin-less package, the options will pass through to less-loader configuration. It seemed like JS being enabled was needed for react-awesome-query-builder to run, which is deprecated. I'm not sure if there is a way to avoid having that on.
I think that should get you past that specific webpack error, I'm not sure if it will make the react-awesome-query-builder demo/example work though.
If you do end up needing to edit the webpack config, you can follow the guide on gatsby's docs.

Syntax Error In IE 11 for this node_moduels

I am getting a syntax error in IE when this component of react is loaded in the webpage. Has anybody got the same problem? This is an inherited package, and a syntax error from node_modules makes no sense?
"use strict";
/* WEBPACK VAR INJECTION */(function(module) {
const colorConvert = __webpack_require__(/*! color-convert */ "./node_modules/color-convert/index.js");
const wrapAnsi16 = (fn, offset) => function () {
const code = fn.apply(colorConvert, arguments);
return `\u001B[${code + offset}m`;
};
const wrapAnsi256 = (fn, offset) => function () {
const code = fn.apply(colorConvert, arguments);
return `\u001B[${38 + offset};5;${code}m`;
};
If you are using newer versions of Node/NPM, check your package.json file -> "browserslist" section.
This is the default "browserslist" created for you if you do not have one defined:
In this case, if you run "npm start" on your LOCAL Environment, Babel will not create Polyfills for IE11 because its not included as a target browser in "development". To get this working, I deleted my node_modules directory completely, ran 'npm install', updated package.json with:
and ran 'npm start.
The reason why this fails is that babel or your other favorite transpiler might ignore node_modules (if that's how its configured), so you need to include it manually because IE does not support arrow function syntax.
First, if you search for wrapAnsi16 or wrapAnsi256 function names online it'll point you to common npm packages, such as: ansi-styles, chalk or color-convert, debug, strip-ansi, etc.
If you are using Webpack you can add the following to your rules:
module: {
rules: [{
exclude: /node_modules\/(?!(color-convert|ansi-styles|strip-ansi|ansi-regex|debug|react-dev-utils|chalk)\/).*/
}]
}
or, easier to read:
module: {
rules: [{
include: [
path.resolve(__dirname, 'node_modules/ansi-styles'),
path.resolve(__dirname, 'node_modules/strip-ansi'),
... other's here...
path.resolve(__dirname, 'src'),
]
}]
}
Hope this helps somebody in the future ;)
TLDR; you don't need this library, just run
npm run build
And it will be excluded from your build.
I have same problem with create-react-app, and I solve it (no). From my discovery, this library should not appear in browser, because it was designed for nodejs environment. Also I found, this library come to me as dependency of jest, and jest is dependency for tests and it come as dependency for react.
So, I run
npm run build
server -s build
And try my application in IE. And it work. So, when you run
npm start
It make file including dev dependencies and other garbage that should not appear in production and in browser at all. When you run
npm run build
It make file only with required project libraries.
I had similar issue #punkbit solution and installing 'react-app-polyfill'
and importing it at the top of the index.js file solved it
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
If it still does not work delete node-modules and reinstall also clear cache in IE.
All the best :)
This problem occurs because your compiled code contains (modern) ES6 syntax whilst IE11 only supports ES5.
A way to fix this is to instruct webpack to specifically compile the mentioned packages into ES5;
module: {
rules: [{
test: /\.(tsx?|js)$/,
include: [
// These dependencies have es6 syntax which ie11 doesn't like.
// Whenever you see a "SyntaxError" that crashes IE11 because of a new lib, add it here.
path.join(__dirname, 'node_modules/react-intl'),
path.join(__dirname, 'node_modules/pkce-challenge'),
path.join(__dirname, 'node_modules/fuse.js')
],
use: [{
loader: 'ts-loader', // Or whatever loader you're using
}]
}]
}
for me this was: fuse.js, pkce-challenge and react-intl.

How to temporarily turn on/off React development mode when using webpack?

I'm using webpack as my bundler and I'd like to test the real performance sometimes without having to actually bundle the whole application. Is there a way how to temporarily turn off React development mode? As far as I know, the production version of React is actually a different file with all the extra debug info stripped but I don't know how to enforce which version should be loaded.
Tell Webpack to use Node's production environment. One way of doing this is to use DefinePlugin in your Webpack config to set the process.env to production:
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify("production")
}
})
]
Also make sure to use a production-ready devtool option, e.g. devtool: 'cheap-module-source-map' and not devtool: 'eval' (also in your Webpack config).
The production version of React is just the .min.js version. From the download page:
We provide two versions of React: an uncompressed version for development and a minified version for production. The development version includes extra warnings about common mistakes, whereas the production version includes extra performance optimizations and strips all error messages.
So if you include this in your asset pipeline, instead of the uncompressed version, you will be able to test your app in 'production' mode.
Assuming you install React 15.0.1 with npm, import react from 'react' or react = require('react') will run ./mode_modules/react/lib/React.js which is React's raw source.
The React docs suggest you use ./mode_modules/react/dist/react.js for development and react.min.js for production.
Should you minify /lib/React.js or /dist/react.js for production, React will display a warning message that you've minified non-production code:
Warning: It looks like you're using a minified copy of the development build of React. When deploying React apps to production, make sure to use the production build which skips development warnings and is faster. See fb.me/react-minification for more details.
react-dom, redux, react-redux behave similarly. Redux displays a warning message. I believe react-dom does too.
So you are clearly encouraged to use the production version from /dist.
However if you minify the /dist versions, webpack's UglifyJsPlugin will complain.
WARNING in ../~/react/dist/react.js
Critical dependencies:
4:478-485 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
# ../~/react/dist/react.js 4:478-4851
You cannot avoid this message because UglifyJsPlugin can only exclude webpack chunks, not individual files.
I use the both the development and production /dist versions myself.
Webpack has less work to do and finishes a bit sooner. (YRMV)
React docs say /dist/react.min.js is optimised for production. I've read no proof, just handwaving, that 'process.env': { NODE_ENV: JSON.stringify(IS_PRODUCTION ? 'production' : 'development') } plus uglify does as good a job as '/dist/react.min.js`.
I get 1 warning message from uglify rather than 3 from the react/redux ecosystem.
You can have webpack use the /dist versions with:
resolve: {
alias: {
'react$': path.join(__dirname, 'node_modules', 'react','dist',
(IS_PRODUCTION ? 'react.min.js' : 'react.js')),
'react-dom$': path.join(__dirname, 'node_modules', 'react-dom','dist',
(IS_PRODUCTION ? 'react-dom.min.js' : 'react-dom.js')),
'redux$': path.join(__dirname, 'node_modules', 'redux','dist',
(IS_PRODUCTION ? 'redux.min.js' : 'redux.js')),
'react-redux$': path.join(__dirname, 'node_modules', 'react-redux','dist',
(IS_PRODUCTION ? 'react-redux.min.js' : 'react-redux.js'))
}
}

How to turn on/off ReactJS 'development mode'?

Started using ReactJS's prop validation feature, which as the docs say only works in 'development mode' for performance reasons.
React seems to be validating the properties of a particular component I've annotated, but I don't remember explicitly turning on 'development mode'.
I tried searching for how to trigger/toggle development mode, but haven't had any luck.
The other answer assumes you are using external pre-built files from react, and while correct that is not how most folks are going to or should consume React as a package. Moreover, at this point most every React library and package also relies on the same convention to toggle dev time helpers off during production. Just using the minified react will leave all those potential optimizations on the table as well.
Ultimately the magic comes down to React embedding references to process.env.NODE_ENV throughout the codebase; these act like a feature toggle.
if (process.env.NODE_ENV !== "production")
// do propType checks
The above is the most common pattern, and other libraries follow it as well. So to "disable" these checks we need to toggle NODE_ENV to "production"
The proper way to disable "dev mode" is through your bundler of choice.
webpack
Use the DefinePlugin in your webpack config like so:
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("production")
})
Browserify
Use the Envify transform and run your browserify build step with NODE_ENV=production ("set NODE_ENV=production" on Windows)
Result
This will produce output bundles that has all instances of process.env.NODE_ENV replaced with the string literal: "production"
Bonus
When minifying the transformed code you can take advantage of "Dead Code Elimination". DCE is when the minifier is smart enough to realize that: "production" !== "production" is always false and so will just remove any code in the if block saving you bytes.
Yeah, it's not really well documented, but on the ReactJS download page it talks about development and production modes:
We provide two versions of React: an uncompressed version for development and a minified version for production. The development version includes extra warnings about common mistakes, whereas the production version includes extra performance optimizations and strips all error messages.
Basically, the unminified version of React is "development" mode, and the minified version of React is "production" mode.
To be in "production" mode, just include the minified version react-0.9.0.min.js
I posted this elsewhere but, frankly, here would be a better place.
Assuming you install React 15.0.1 with npm, import react from 'react' or react = require('react') will run ./mode_modules/react/lib/React.js which is React's raw source.
The React docs suggest you use ./mode_modules/react/dist/react.js for development and react.min.js for production.
Should you minify /lib/React.js or /dist/react.js for production, React will display a warning message that you've minified non-production code:
Warning: It looks like you're using a minified copy of the development build of React. When deploying React apps to production, make sure to use the production build which skips development warnings and is faster. See fb.me/react-minification for more details.
react-dom, redux, react-redux behave similarly. Redux displays a warning message. I believe react-dom does too.
So you are clearly encouraged to use the production version from /dist.
However if you minify the /dist versions, webpack's UglifyJsPlugin will complain.
WARNING in ../~/react/dist/react.js
Critical dependencies:
4:478-485 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
# ../~/react/dist/react.js 4:478-4851
You cannot avoid this message because UglifyJsPlugin can only exclude webpack chunks, not individual files.
I use the both the development and production /dist versions myself.
Webpack has less work to do and finishes a bit sooner. (YRMV)
React docs say /dist/react.min.js is optimised for production. I've read no proof that 'process.env': { NODE_ENV: JSON.stringify(IS_PRODUCTION ? 'production' : 'development') } plus uglify does as good a job as '/dist/react.min.js`. I've read no proof you get the same resulting code.
I get 1 warning message from uglify rather than 3 from the react/redux ecosystem.
You can have webpack use the /dist versions with:
resolve: {
alias: {
'react$': path.join(__dirname, 'node_modules', 'react','dist',
(IS_PRODUCTION ? 'react.min.js' : 'react.js')),
'react-dom$': path.join(__dirname, 'node_modules', 'react-dom','dist',
(IS_PRODUCTION ? 'react-dom.min.js' : 'react-dom.js')),
'redux$': path.join(__dirname, 'node_modules', 'redux','dist',
(IS_PRODUCTION ? 'redux.min.js' : 'redux.js')),
'react-redux$': path.join(__dirname, 'node_modules', 'react-redux','dist',
(IS_PRODUCTION ? 'react-redux.min.js' : 'react-redux.js'))
}
}
For webpack based build, I used to setup separate webpack.config.js for DEV and PROD. For Prod, resolve the alias as below
alias: {
'react$': path.join(__dirname, 'node_modules', 'react','dist','react.min.js'),
'react-dom$': path.join(__dirname, 'node_modules', 'react-dom','dist','react-dom.min.js')
}
You can find the working one from here
If you're working from something like this ReactJS.NET / Webpack tutorial, you can't use process.env to switch React development mode on/off as far as I can tell. This sample links to react.js directly (see Index.cshtml), so you just have to pick .min.js or the non-minified variant by changing the URL.
I'm not sure why that is the case, because the sample's webpack.config.js has a comment that seems to imply the externals: { react: 'React' } would do the job, but then goes ahead and includes react directly into the page.
I use a manual build process that runs through Webpack, so it was a two-step process for me:
Set the environment variable from package.json using the cross-env package:
"scripts": {
"build-dev": "cross-env NODE_ENV=development webpack --config webpack.config.js",
"build-prod": "cross-env NODE_ENV=production webpack --config webpack.config.js"
}
Change the webpack.config.js file to use the environment variable (which is passed-on to React to determine if we are in development or production mode), and disable minimizing the produced bundle if we are in development mode so we can see the actual names of our components. We need to use webpack's optimization property in our webpack.config.js file for this:
optimization: {
nodeEnv: process.env.NODE_ENV,
minimize: process.env.NODE_ENV === 'production'
}
webpack v4.41.5, React v16.9.19, cross-env v7.0.0, node v10.16.14
For only Webpack v4 users:
Specifying mode: production and mode: development in your Webpack config will define process.env.NODE_ENV using the DefinePlugin by default. No additional code necessary!
webpack.prod.js (taken from docs)
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
});
And in our JS:
console.log(process.env.NODE_ENV) // --> 'development' or 'production'
Webpack Docs: https://webpack.js.org/guides/production/#specify-the-mode

Resources