create-react-app: Apps with `react-scripts` v4.0.0 do not work in IE11

Describe the bug

After upgrading my app from react-scripts 3.4.4 to 4.0.0 I see that app does not work in IE11 at all. Additionally - when I created a new app from the latest CRA, added react-app-polyfill I see it’s also not working at all. image

My package.json looks like this:

{
  "name": "cra4",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "@types/jest": "^26.0.15",
    "@types/node": "^12.0.0",
    "@types/react": "^16.9.53",
    "@types/react-dom": "^16.9.8",
    "react": "^17.0.1",
    "react-app-polyfill": "2.0.0",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.0",
    "typescript": "^4.0.3",
    "web-vitals": "^0.2.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  }
}

The same error appears also when I run yarn build and serve from build/ directory.

Did you try recovering your dependencies?

It’s the default CRA behaviour.

Which terms did you search for in User Guide?

(Write your answer here if relevant.)

Environment

Environment Info:

  current version of create-react-app: 3.4.1
  running from C:\Users\XXX\AppData\Local\Yarn\Data\global\node_modules\create-react-app

  System:
    OS: Windows 10 10.0.19041
    CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor
  Binaries:
    Node: 14.14.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.5 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 6.14.8 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: 44.19041.423.0
    Internet Explorer: 11.0.19041.1
  npmPackages:
    react: ^17.0.1 => 17.0.1
    react-dom: ^17.0.1 => 17.0.1
    react-scripts: 4.0.0 => 4.0.0
  npmGlobalPackages:
    create-react-app: Not Found

Steps to reproduce

  1. Create new CRA app with typescript template used
  2. yarn add react-app-polyfill
  3. Add import 'react-app-polyfill/ie11'; import 'react-app-polyfill/stable'; to the top of index.tsx
  4. yarn start
  5. Observe that site works perfectly in normal browsers and it’s a blank screen in the IE

Expected behavior

Site should work (I am not expecting miracles. It’s a IE overall, but blank page is very bad)

Actual behavior

image

Reproducible demo

(Paste the link to an example project and exact instructions to reproduce the issue.)

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 34
  • Comments: 50

Most upvoted comments

I think the new jsx transform is causing this, try disabling it either by adding /** @jsxRuntime classic */ to the top of your main index.js where you also import your polyfills - or set DISABLE_NEW_JSX_TRANSFORM=true environmental variable. In my case either of those fixes this.

My guess is that by importing polyfills first you can get them to load before react, but you can’t get them to load before the import {jsx as _jsx} from 'react/jsx-runtime'; line that the compiler inserts.

my workaround:

import 'react-app-polyfill/ie11'; // import 'react-app-polyfill/stable'; import 'core-js/stable'; import 'regenerator-runtime/runtime';

None of the above seems to be working.

IE11 errors with

image

Clicking on the error brings us here

image

IE version

image

Here’s a super simple example to reproduce

  1. npx create-react-app ie11app
  2. yarn add react-app-polyfill
  3. Update the index.js
/** @jsxRuntime classic */
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';
import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
    <div>Come on</div>,
  document.getElementById('root')
);
  1. Add ie 11 to browerslist in package.json
{
  "name": "ie11app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "react": "^17.0.1",
    "react-app-polyfill": "^2.0.0",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.0",
    "web-vitals": "^0.2.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "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",
      "ie 11"
    ]
  }
}
  1. yarn start

@Dan503 @pluma I tried both, "ie >= 11" and removing import 'react-app-polyfill/stable';, but still no luck.

Could you be so kind and create a new npx create-react-app ie11app and check if it actually is still working for you on IE11?

Thank you

Update: Reverting back to "react-scripts": "^3.0.0" works on IE 11 even with "react": "^17.0.1", But "react-scripts": "4.0.0" is still broken for me

We ran into this same issue. We had already converted a lot of our code base to the new JSX format though (the format where you don’t need to import React anymore).

Good news! We were able to keep the all of the new JSX syntax!

We only had to apply this to the top of our src/index.js file.

/** @jsxRuntime classic */
import 'react-app-polyfill/ie11'

// IE11 needs "jsxRuntime classic" for this initial file which means that "React" needs to be in scope
// https://github.com/facebook/create-react-app/issues/9906
import React from 'react'

Added the comment because otherwise we could see this being something people wouldn’t understand and would probably leave hanging around in the codebase forever.

The only downside is that we don’t get to have treeshaking reduce our bundle size which was one of the key reasons we upgraded to React 17 in the first place 😦

Try removing import 'react-app-polyfill/stable'; from index.js.

You only need import 'react-app-polyfill/ie11'

Not works for me. I solved it by put followed code to the top of the index.tsx:

/** @jsxRuntime classic */
import "react-app-polyfill/ie11";
import "react-app-polyfill/stable";
// IE11 needs "jsxRuntime classic" for this initial file which means that "React" needs to be in scope
// issue: https://github.com/facebook/create-react-app/issues/9906
import React from "react";

....

@Pierre-Do Yes, I updated my issue with the missing information. I forgot that IE11 is not supported out of the box, but with react-app-polyfill is not working as well 😦

Hello, I am reading your comments and I wanted to share with you the solutions I obtained by doing research.

  • First of all react-scripts@4.0.1 unfortunately does not support ie11 for prod or dev. ( #10272 )

I created my project with create-react-app and installed react-app-polyfill. It works with react-scripts@4.0.1. These are the solutions that give successful results for me;

1. React-scripts version can be downloaded. (Example: react-scripts@3.4.4 successful.) 2. Add this to the first line of src/index.

/** @jsxRuntime classic */
import "react-app-polyfill/ie11";
import "react-app-polyfill/stable";

3. Add this to the first line of src/index.

  • It doesn’t work with react-app-polyfill/stable in this usage.
  • It should be used with the core-js and regenerator-runtime suggested by babel-polyfill. https://babeljs.io/docs/en/babel-polyfill
import 'react-app-polyfill/ie11';
import 'core-js/stable';
import 'regenerator-runtime/runtime';

4. Define .env

DISABLE_NEW_JSX_TRANSFORM=true

It was a solution text consisting of the information I obtained from you. Thank you all. Hope it helps those who are in search.

We have had some luck by upgrading to react-scripts v4.0.1, however it didn’t consistently work across all of our projects. We have no idea why.

For the projects it did work in, we were able to remove /** @jsxRuntime classic */ and import React from "react"; from index.js and have it still work in IE11.

So if you are still struggling, Try upgrading to v4.0.1. It might work for you.

@gynekolog solutions is working for me (pure JS)

Here are my 3 first lines in index.js

/** @jsxRuntime classic */
import 'react-app-polyfill/ie11';
import 'react-app-polyfill/stable';

I also tried many of these solutions. The only one that worked was downgrading react-scripts to 3.4.4.

The workaround isn’t working for me, the error remains.

I can confirm that @ezBill solution works for me. Maybe react-app-polyfill need to be fixed?

change “react-scripts”: “4.0.3” to “react-scripts”: “4.0.0” works for me

@borodean I think you just unlocked the method for enabling tree shaking support!

src/index.ts

import "react-app-polyfill/ie11";
import "./bootstrap";

src/bootstrap.tsx:

import { StrictMode } from "react";
import ReactDOM from "react-dom";

import App from "components/App";

ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  document.getElementById("root")
);

That now only loads in StrictMode from React rather than the entire React library!

I think you can get even more savings by importing ReactDOM like this as well:

import { render } from "react-dom";

// ...

render(
    // ...
)

@asezgin58 I’m going to break down each line explaining what the purpose of each line is.

/** @jsxRuntime classic */

The new version of React uses a new method for converting JSX syntax into js that browsers understand. This line tells the compiler to use the old deprecated compilation method instead of the new fancy one.

import 'react-app-polyfill/ie11'

By default, React uses code that isn’t natively supported in IE11. This line loads up the bare minimum number of polyfills needed to run a “Hello World” React App in IE11.

import 'core-js/stable'

The reason why this line adds so much JavaScript weight to the page is because it adds basically every single polyfill there is in the core-js library to your JavaScript bundle. This an extremely inefficient method of doing IE11 polyfills. It is much better to load in individual polyfills from the core-js library as you need them. The core-js documentation explains how to do this syntactically. You need to read the errors that you are getting in IE11 to figure out what polyfills you are currently missing from your project that you need.

import React from 'react'

Since we are using the old compilation method, we need to import React the old fashioned way. index.js is the only file that needs to be compiled in the old fashion way though. None of the other files need to import React since they compile using the new method.

Note: if you are using TypeScript, the last line needs to look like this instead:

import * as React from 'react'

@Dan503 You are right. I noticed that the following use is sufficient. But it still doesn’t work on my project I told you about. ( The project link I mentioned; https://github.com/asezgin58/recoil-essential-app )

src/index

/** @jsxRuntime classic */
import 'react-app-polyfill/ie11';

I want to share my new experience on this subject. I want to list the steps I followed. ( react@17.0.1, react-scripts@4.0.1 )

1. I created a new project with create-react-app and just added “ie 11” into package.json/browserList.

Result: The project is now running on ie11 in its default form.

2. But with the codes I added, the need for polyfill arose. Therfore I installed react-app-polyfill and imported it into the src/index file.

3. I deleted the node-modules/.cache folder and restarted the project with “npm start”. It still didn’t work 😦

4. And I applied the solution that @Dan503 mentioned. My project now runs on ie11. 😃

Note : If we use it by importing core-js/stable file; I observed that the build size increases a lot. I guess /** @jsxRuntime classic */ is more convenient to use. Because it does not have a serious effect on the build size.

My new project link : https://github.com/asezgin58/context-essential-app

But I still don’t understand why the same solution didn’t work for the project I’m talking about. Because my new project is no different from its dependency. 😦

Thanks @Dan503 👍

@asezgin58 ok the issue is that you still need core-js to give you some polyfills.

So the bare minimum that you need to do in index.js is this:

/** @jsxRuntime classic */
import 'react-app-polyfill/ie11'
import 'core-js/stable'
import React from 'react'

You don’t need regenerator-runtime/runtime.

Note that you don’t need to import the React variable in any of your other files now. eg. in App.tsx you are importing React when you don’t need to. Only index.js needs to import the React variable for the sake of IE compatibility.

I left off import 'core-js/stable' in my initial answer since we handle polyfills more granularly in our projects and already had them loaded when upgrading to react-scripts v4.

Thanks to @pluma, what I found to be the cleanest solution was to extract all the code from index.tsx, except for the polyfill imports into a separate file. The point is to have the polyfills loaded before any JSX code is referenced.

This way there is absolutely no need to disable the JSX transformations. Unfortunately, this still won’t fix the hot reload, as neither of the solutions above.

src/index.ts:

import "react-app-polyfill/ie9";
import "react-app-polyfill/stable";

import "./bootstrap";

src/bootstrap.tsx:

import React from "react";
import ReactDOM from "react-dom";

import App from "components/App";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

Hi all. A bit late on this issue but I’ve plucked my hair to find a solution to this issue until I stumbled upon on this issue and several other similar/duplicate ones. Thanks to all of you who provided solution(s) to this issue, and big props to @msbarry !

If I may give a little advise is that, this needs to be relayed to the changelog as a solution to people who work in projects that still support IE11 (such as myself), to make their life easier when upgrading from 3.x.x to 4.0.1. I bet so many of us could’ve been saved minutes/hours if we had such information in front of us.

@asezgin58 you shouldn’t need to downgrade to react-scripts 3.4.4 and you don’t need to disable the new JSX transforms.

With React v4.0.1, as long as you have this at the top of your src/index.js file the project should work in IE11:

/** @jsxRuntime classic */
import "react-app-polyfill/ie11";
import React from 'react'

That solution has worked consistently for us across all our projects.

https://github.com/facebook/create-react-app/issues/9906#issuecomment-720905753

(Note: we are handling the importing of polyfills for non-React library code manually instead of letting Babel import polyfills automatically)

FWIW we split the index.ts file into an init.ts and main.tsx file where init.ts imports all relevant polyfills and main.tsx is the actual entrypoint (containing React code) and index.ts just imports both in sequence. This ensures any modules that may need the polyfills to be in effect are loaded after the polyfills and the naming ensures that even when using automatic sorting of imports the polyfills come before the main entry point.

This may be a more workable solution than having to work around this issue.

I was experiencing the same issue. Even though I’m using react-app-polyfill, my blew up on IE11 and I received error message #31. Because of this error message I was starting to think it was related to this long-resolved React issue.

The good news: After updating react-scripts to ^4.0.2, the issue is resolved for me.

PS: @Dan503 Doesn’t that breach the react/react-in-jsx-scope convention?

@BerndWessels package.json/browserList should contain “ie 11”. Then please install react-app-polyfill. No other problem appears.

My polyfills look like this and I have no problem with IE11:

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

Note that these must come above any other imports that would break without these polyfills in place. Plus the polyfill doesn’t provide some more esoteric APIs like TextEncoder so you’ll still need to load polyfills for those if you need them for some reason.