Disable/Hide "Download the React DevTools..." - reactjs

How do you completely disable or hide the "persistent" console message: Download the React DevTools for a better development experience while in development?

As of React 16.2.0, you can add a line like this to your webpack configuration:
new webpack.DefinePlugin({
'__REACT_DEVTOOLS_GLOBAL_HOOK__': '({ isDisabled: true })'
}),
If not using webpack you can put, somewhere in a module imported before react:
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = { isDisabled: true };
This disables all logs about React DevTools.

Put this line somewhere in the global scope (it won't work if you put it inside a bundled module):
__REACT_DEVTOOLS_GLOBAL_HOOK__ = true;
Here's a related gist from Ryan Florence that's the basis for the above hack:
if (
process.env.NODE_ENV === 'production' &&
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ &&
Object.keys(window.__REACT_DEVTOOLS_GLOBAL_HOOK__._renderers).length
) {
window.__REACT_DEVTOOLS_GLOBAL_HOOK__._renderers = {}
}
Update: React 16 has a new console warning that reads Warning: The installed version of React DevTools is too old and will not work with the current version of React. Please update React DevTools. To disable it, put this code in the global scope:
__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
supportsFiber: true,
inject: function() {},
onCommitFiberRoot: function() {},
onCommitFiberUnmount: function() {},
};

Put something like that in your html
<script>{`
(function() {
var info = console.info
console.info = function (message) {
if (!/Download the React DevTools/.test(message)) info.apply(console, arguments)
}
})()
`}</script>

If you use Storybook with Angular or Vue, or any other framework - the message "Download the React DevTools for a better development experience:" in the devtools does't make any sense. And even for folks who use React - it may be annoying.
I tried all answers in this thread, however, they don't really work anymore. Even the accepted answer is no valid anymore. So, this is what works right now for Storybook 6+ and Webpack 4/5:
The message comes from the Storybook Manager (which is created with React I guess). Create file manager.js in your .storybook dir. It should be a sibling of your other storybook config files, e.g. main.js, privew.js, etc..
Add the following code to disable a range of React messages:
// .storybook/manager.js
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = {
_renderers: {},
supportsFiber: true,
inject: () => ({}),
onCommitFiberRoot: () => ({}),
onCommitFiberUnmount: () => ({}),
};
Re-run your build and the message should disappear. This will also remove another warning from React: The installed version of React DevTools is too old and will not work with the current version of React

Here's a solution for Next.JS (works with 12.1.6 at time of writing):
In your project root, add the following lines to next.config.js:
module.exports = {
// add your other next config settings here
webpack: (
config,
{ buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }
) => {
config.plugins = [...config.plugins,
new webpack.DefinePlugin({
'__REACT_DEVTOOLS_GLOBAL_HOOK__': '({ isDisabled: true })'
})
]
// Important: return the modified config
return config
},
}
This solution combines Dan Abramov's answer with the Next.js documentation description of modifying webpack config.

Also, locally you could just comment that part of code.
Search all file in "node_modules" for "React DevTools", you will get 2 results, react-dom.js and ReactDOM.js:
react-dom.js, navigate to line 5430, make line 5430 - 5437 to a comment, save.
ReactDOM.js, navigate to line 68, make line 68 - 75 to a comment, save.
Restart your app server.
I hope this method is not against the React License.

Related

Webpack Module Federation React Version issue in NextJS

I have a react app that I need to run inside a NextJS host app and run on it's own.
In the NextJS example at https://github.com/module-federation/module-federation-examples/tree/master/nextjs-react there are notes that:
NOTE: If version: '0' is omitted, you'll encounter an issue where a copy of react will be downloaded from the remoteEntry.
NOTE: Another issue you may run into is an invalid hook call if you are federating a component that uses react hooks. This is directly related to multiple copies of react running at the same time. The above resolves this.
I have set up a remote app with ModuleFederationPlugin:
shared: {
react: {
singleton: true,
requiredVersion: false,
version: "0"
},
"react-dom": {
singleton: true,
requiredVersion: false,
version: "0"
}
}
This works when running inside a NextJS host. But when I run my federated app on its own, I get TypeError: n.n(...)(...).createContext is not a function. If I remove version: "0" then I get invalid hook call when run inside the NextJS host.
Is it possible to handle both cases, or have a fallback in case there is no react version present in shared scope?
I found that I had to add:
resolve: {
alias: {
react: path.resolve("./node_modules/react")
}
}

babel: polyfill Array.from for IE11 support

I'm currently having trouble getting my React application working in IE11. The problem seems to be that some of the newer ES6 stuff isn't available in IE11. So my goal is to polyfill the missing functionality. I'm using nwb [1] which is a zero-configuration setup for React applications. However, I'm unsure how to configure Babel (or Webpack ?) to polyfill certain methods like Array.from. It looks like fetch, Promise, and Object.assign are all polyfill-ed but not Array.from for example. Any help would be greatly appreciated.
Here is my nwb.config file:
module.exports = {
type: 'react-app',
webpack: {
define: {
VERSION: JSON.stringify(require('./package.json').version),
HOSTNAME: JSON.stringify(process.env.NODE_ENV === 'production' ?
'https://xyz.azurewebsites.net' :
'http://localhost:8080')
},
rules: {
babel: {
test: /\.jsx?/
}
},
extra: {
resolve: {
extensions: ['.jsx']
},
devtool: '#inline-source-map'
},
html: {
favicon: 'src/img/favicon.ico'
}
}
};
Thanks,
[1] A toolkit for React app. https://github.com/insin/nwb
Sounds like you need to add babel-polyfill to your project.
This will emulate a full ES2015+ environment and is intended to be
used in an application rather than a library/tool. This polyfill is
automatically loaded when using babel-node.
This means you can use new built-ins like Promise or WeakMap, static
methods like Array.from or Object.assign, instance methods like
Array.prototype.includes, and generator functions (provided you use
the regenerator plugin). The polyfill adds to the global scope as well
as native prototypes like String in order to do this.
The easiest way for you would probably be to import it at the top of your main js file:
import 'babel-polyfill';

Can't resolve $element after minification

I've got a strange bug that only appears when running my web appliction in karaf but not on the webpack-dev-server. When running the web app from Karaf when I open the dialog, I get this error in the browser console
angular.js:14516 Error: [$injector:unpr] Unknown provider: nProvider <- n
http://errors.angularjs.org/1.6.3/$injector/unpr?p0=nProvider%20%3C-%20n
The component is responsible for displaying a table. The columns should be editable so i've implemented a stock dialog from the angular material demos. See -> https://material.angularjs.org/latest/demo/dialog and a multi select with the option to search -> https://material.angularjs.org/latest/demo/select
Here follows the code:
ctrl.editColumns = (event) => {
$mdDialog.show({
template: require('./edit-column-dialog.template.html'),
clickOutsideToClose: true,
scope: $scope,
preserveScope: true,
controller: EditColumnsDialogController
})
}
function EditColumnsDialogController ($element) {
ctrl.searchTerm = ''
ctrl.copySelectedColumns = ctrl.selectedColumns
// The md-select directive eats keydown events for some quick select
// logic. Since we have a search input here, we don't need that logic.
$element.find('input').on('keydown', (ev) => {
ev.stopPropagation()
})
}
I use $element for the reason detailed in the comment above. What I can't get my head around is that this works fine on the web pack dev server. The only difference between the settings for web pack are:
// Add build specific plugins
if (isProd) {
config.plugins.push(
// Only emit files when there are no errors
new webpack.NoEmitOnErrorsPlugin(),
// Minify all javascript, switch loaders to minimizing mode
new webpack.optimize.UglifyJsPlugin({
sourceMap: true
}),
// Copy assets from the public folder
// Reference: https://github.com/kevlened/copy-webpack-plugin
new CopyWebpackPlugin([{
from: path.join(__dirname, '/app/public')
}])
)}
Any answers are much appreciated.. or suggestions for isolating the problem!
Minifiers break code that uses Implicit Annotation. Instead, use $inject Property Annotation:
//USE $inject property annotation
EditColumnsDialogController.$inject = ["$element"];
function EditColumnsDialogController ($element) {
ctrl.searchTerm = ''
ctrl.copySelectedColumns = ctrl.selectedColumns
// The md-select directive eats keydown events for some quick select
// logic. Since we have a search input here, we don't need that logic.
$element.find('input').on('keydown', (ev) => {
ev.stopPropagation()
})
}
From the Docs:
Implicit Annotation
Careful: If you plan to minify your code, your service names will get renamed and break your app.
— AngularJS Developer Guide - Implicit Dependency Annotation

How to get promises to work in IE10 with react

I am trying to fetch data using promise in my react application. I installed and implemented this polyfill es6-promise but works for IE11 on window 8 but IE10 window 7 is says 'promise are undefined'. I assumed the polyfill is meant to cover all IE9+, but it is just not working for me. Has anyone come across this problem? Am I missing something in the implementation of the es6-promise polyfill with webpack??
// calling it my jsx file
import React, { PropTypes } from 'react';
import es6promise from 'es6-promise'; // not sure if I need this in the jsx file also??
promise.polyfill();
import 'isomorphic-fetch';
class App extends React.Component {
...
}
App.propTypes = propTypes;
export default App;
webpack.config.js
var promise = require('es6-promise').polyfill();
switch (TARGET) {
case 'build':
module.exports = mergeConfig({
plugins: [
// Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
// Minify all javascript. Loaders are switched into minimizing mode
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.DefinePlugin({
'process.env': {
// This has effect on the react lib size
'NODE_ENV': JSON.stringify('production')
}
}),
new webpack.ProvidePlugin({
PROMISE: promise
})
]
});
break;
You can try babel-polyfill.
After install it as dependency.
Import it in your app.js
import 'babel-polyfill';
I have an another interesting solution (it works for me in that case). I didn't want to import a polyfill into every file so I provided via WebpackProvidePlugin.
new webpack.ProvidePlugin({
"Promise": "babel-polyfill",
'fetch': 'imports-loader?this=>global!exports-loader?
global.fetch!whatwg-fetch'
})
So now I can use these stuff without importing into every file. And a very important note. Some resources are suggesting to use es6-promise instead babel-polyfill, I tried to use it but it doesn't work for me. Looks like es6-promise-polyfill didn't work in case of using webpack + babel. So I switched to the babel-polyfill. Tested in the IE11 and all is fine.
Hope it helps.
Best Regard. Velidan.
I recommend using the native-promise-polyfill npm module, especially if you don't need the other features babel-polyfill includes:
This means you can use new built-ins like Promise or WeakMap, static methods like Array.from or Object.assign, instance methods like Array.prototype.includes, and generator functions

referencing an amd module(arcgis) in webpack app

I'm building a react app with webpack and i need to incorporate arcgis maps into a react component. I have know idea how to bring this into my project. I've tried creating an arcgis directory with an index.js of the built javascript and trying to reference that:
import {Map} from 'arcgis/index'
That doesn't work. I then just tried to include the css/js script tags directly into my index.html but when I try to require them, like in the example, webpack obviously can't find them. Is there some way to tell webpack to ignore require calls in my src file so it gets handled by the browser? I'm trying and failing at doing the following:
import React from 'react'
export default class EsriMap extends React.Component {
componentDidMount() {
const _this = this
require(["esri/map", "dojo/domReady!"], function(Map) {
var map = new Map(_this.refs.map, {
center: [-118, 34.5],
zoom: 8,
basemap: "topo"
});
});
}
render() {
return (
<div ref="map"></div>
)
}
}
You may want to try this https://github.com/tomwayson/esri-webpack-babel .
This method is nice because it doesn't bog down the build. You pull in the ESRI Api from the CDN, and tell webpack that it's an external.
//Add this...
externals: [
// Excludes any esri or dojo modules from the bundle.
// These are included in the ArcGIS API for JavaScript,
// and its Dojo loader will pull them from its own build output
function (context, request, callback) {
if (/^dojo/.test(request) ||
/^dojox/.test(request) ||
/^dijit/.test(request) ||
/^esri/.test(request)
) {
return callback(null, "amd " + request);
}
callback();
}
],
//And this to you output config
output: {
libraryTarget: "amd"
},
When your app loads you bootstrap you webpack modules using Dojo in a script tag.
<!-- 1. Configure and load ESRI libraries -->
<script>
window.dojoConfig = {
async: true
};
</script>
<script src="https://js.arcgis.com/4.1/"></script>
<!-- Load webpack bundles-->
<script>
require(["Angular/dist/polyfills.bundle.js", "Angular/dist/vendor.bundle.js", "Angular/dist/app.bundle.js"], function (polyfills, vendor, main) { });
</script>
I've got it working with an Angular 2 App I'm working on. The only downside is I haven't yet got the unit tests to run right using Karma. I've only been working on that a few hours now.. Hope to have a solution to the testing issue soon.
#getfuzzy's answer will work well as long as you don't need to lazy load the ArcGIS API (say for example only on a /map route).
For that you will want to take the approach I describe in this answer
This blog post explains why you need to use one of these two approaches and explains how they work as well as the pros/cons of each.
I think you can try using bower version of esrijsapi. Doc link

Resources