create-react-app: Webpack Hot Dev Client Breaks on older browsers

Is this a bug report?

yes

Did you try recovering your dependencies?

no

Which terms did you search for in User Guide?

hot dev

Environment

System: OS: macOS High Sierra 10.13.6 CPU: x64 Intel® Core™ i7-6820HQ CPU @ 2.70GHz Binaries: Node: 8.12.0 - /usr/local/opt/node@8/bin/node Yarn: 1.10.1 - /usr/local/bin/yarn npm: 6.4.1 - /usr/local/opt/node@8/bin/npm Browsers: Chrome: 69.0.3497.100 Safari: 12.0 npmPackages: react: ^16.5.2 => 16.5.2 react-dom: ^16.5.2 => 16.5.2 react-scripts: 2.0.4 => 2.0.4 npmGlobalPackages: create-react-app: 2.0.0-next.2150693d

Steps to Reproduce

(Write your steps here:)

  1. npx create-react-app my-app
  2. cd my-app
  3. yarn start
  4. Navigate to app url in old browser that does not have map. E.g. Android 4.4 default browser or ie9 (I used Android 4.4)

Expected Behavior

Default Screen Loads

Actual Behavior

Blank Screen, connecting the debugger reveals the console error Map is not defined

This is caused by a Map call from ansi-styles which is required by chalk.

screen shot 2018-10-07 at 02 00 09

To get past this I added require('react-app-polyfill/ie9'); to the top of webpackHotDevClient (Delete the babel loader cache if you do this). This gets further but then failes on setPrototypeOf. Using the catch all require('core-js'); allows the app to work as expected.

screen shot 2018-10-07 at 02 02 21

Note: the yarn build version always works because the hot dev client is not present

I am not sure if this is something CRA actually wants to support, I think some documentation that the dev mode yarn start may not work with older browsers will be enough.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 9
  • Comments: 44 (1 by maintainers)

Commits related to this issue

Most upvoted comments

I found the dependencies cause the bug

create-react-app -> react-scripts/config/webpack.config.js -> react-dev-utils/webpackHotDevClient.js -> react-dev-utils/formatWebpackMessages.js -> chalk -> ansi-styles -> Map

and I think we need setupPolyfill ( just like setupProxy),it should be insert before webpackHotDevClient:

entry: [
  paths.setupPolyfill,
  isEnvDevelopment &&
  require.resolve('react-dev-utils/webpackHotDevClient'),
  // Finally, this is your app's code:
  paths.appIndexJs,
]

@cliedeman do you have import 'react-app-polyfill/ie9'; as the very first line of src/index.js?

Create a new create-react-app, add react-app-polyfill, update index.js to include the pollyfills, update browserlist to have ie 11 in both prod and dev, and it works in build, but fails in dev, because of the websocket. Workarounds presented here haven’t worked for me. I’ve been having to test changes by doing builds and static serving.

@kareemali-afs As a temporary solution to debug in IE you can disable webpackHotDevClient

  • Add debug mode to scripts
  "scripts": {
    "start": "react-app-rewired start",
    "start:debug": "DEBUG_MODE=true react-app-rewired start",
  • update config-overrides.js :
const {
  override,
  babelInclude,
} = require('customize-cra');
const path = require('path');

module.exports = override(
  (config) => {
    if (process.env.DEBUG_MODE) {
      config.entry.shift(); // remove webpackHotDevClient (first as default)
      config.entry.unshift(require.resolve('react-app-polyfill/stable'));
    }

    return config;
  },
  babelInclude([path.resolve('src')])
);

I downgrade CRA to 3.2.0 to make it work.

I finally have a workaround after looking at this for a couple of days

I had to change the client for WebpackDevServer from react-dev-utils/webpackHotDevClient to the alternative of webpack/hot/dev-server

You have to go to your webpack.config.js file and swap out this line:

isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient'),

with this one:

isEnvDevelopment && require.resolve('webpack/hot/dev-server'),

Thanks to @lomocc comment, I sorted it out that way: I added a paths.setupPolyfill in ./config/webpack.config.js like he said:

entry: [
  paths.setupPolyfill,
  isEnvDevelopment &&
  require.resolve('react-dev-utils/webpackHotDevClient'),
  // Finally, this is your app's code:
  paths.appIndexJs,
]

and then in the ./config/paths.js I added and export:

module.exports = {
  //  ... all the exports
  appNodeModules: resolveApp('node_modules'),
  setupPolyfill: resolveApp('node_modules/react-app-polyfill/ie9'), // added
};

I also needed the es6-sham.min.js script to make it work, so in my index.html I added these lines:

<% if (process.env.NODE_ENV === 'development') { %>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.5/es6-sham.min.js"></script>
<% } %>

You do NOT have to eject from CRA.

Example: https://github.com/ThekhoN/create-react-app-ie11

Steps:

  1. Install react-app-polyfill
    npm i react-app-polyfill

  2. Import react-app-polyfill/ie11 at the TOP of index.js
    import 'react-app-polyfill/ie11'

3. Delete .cache in /node_modules

4. Add ie11 meta tag in index.html (in public folder)
<meta http-equiv="X-UA-Compatible" content="IE=11">

@Nickman87

My temp solution, put this in public/index.html

<% if (process.env.NODE_ENV === 'development') { %>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.5/es6-sham.min.js"></script>
<% } %>

https://gist.github.com/lomocc/a73ec03d7d01a319098ee90165f74c24

But I still expected it to work after adding the opt in polyfills

After reading all the comments this what works for my app:

  1. Install react-app-polyfil npm i react-app-polyfil
  2. Import react-app-polyfill in index file import "react-app-polyfill/ie11" import "react-app-polyfill/stable"
  3. Add ie11 to browserslist in package.json "development": [ "ie 11", ]
  4. Delete node modules rm -rf node_modules
  5. Clean the npm cache npm cache clean --force
  6. Install node modules npm install
  7. Start the project

After reading this comment, I found the following solution works with hot reload. I’m on v3.4.1 of react-scripts

  1. In my local node_modules folder, I modified one file in react-dev-utils (a create-react-app dependency) by removing the offending function call and the chalk import statement

  2. Then I used patch-package to patch my project’s react-dev-utils

  3. added the package for CRA’s polyfills

import "react-app-polyfill/ie9"
import "react-app-polyfill/stable"
  1. I added a meta tag to <head /> element to public/index.html. (optional) It prevents IE users from enabling its “compatibility” mode
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

Its also possible browserlist’s development environment may need additional configuration.

I still have the same issue, It’s a typescript react app that’s created using CRA This is my browserlist

"browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all",
      "ie 11"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version",
      "last 1 ie version"
    ]
  }

And the first two lines of index.tsx are

import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';

This is my tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react",
    "sourceMap": true,
    "baseUrl": ".",
    "outDir": "build/dist"
  },
  "include": [
    "src"
  ]
}

It’s working the build works fine, I have this problem only with npm start.

I tried removing the node_modules and re-run it but I still face the same issue.

@activebiz can u try again. I updated the repo by adding “IE 11” in the browserslist.

There seems to be some caching issue happening at IE11’s end. Try clearing the IE11 browser cache. Running npm cache clean --force also seems to resolve the issue.

Eject create-react-app

@seanbecker15 Just to mention that you can avoid ejecting by using customize-cra or rescripts (they’re both about equally as good) and re-ordering the webpack config as you require.

CRA doesn’t support old browsers anymore by default. https://reactjs.org/blog/2018/10/01/create-react-app-v2.html#breaking-changes

I finally have a workaround after looking at this for a couple of days

I had to change the client for WebpackDevServer from react-dev-utils/webpackHotDevClient to the alternative of webpack/hot/dev-server

You have to go to your webpack.config.js file and swap out this line:

isEnvDevelopment && require.resolve('react-dev-utils/webpackHotDevClient'),

with this one:

isEnvDevelopment && require.resolve('webpack/hot/dev-server'),

@a1g0rithm This worked for me, thank you very much.

@kareemali-afs - I published the repo with the craco config I made for @rjcnd105, take a look at the changes I’ve made. It works for the very old, embedded browser I use (same WebKit engine as PhantomJS 2.1 uses, with capabilities similar to Safari 6). I attempted to add IE 11 support, however, I did not test it (don’t have an environment for it). Give it a try 😃

Eject create-react-app

@seanbecker15 Just to mention that you can avoid ejecting by using customize-cra or rescripts (they’re both about equally as good) and re-ordering the webpack config as you require.

Do you mind adding how?