Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React app not rendering in IE11 and below #8379

Closed
FarhadG opened this issue Nov 22, 2016 · 49 comments
Closed

React app not rendering in IE11 and below #8379

FarhadG opened this issue Nov 22, 2016 · 49 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@FarhadG
Copy link

FarhadG commented Nov 22, 2016

Do you want to request a feature or report a bug?
BUG

What is the current behavior?
App doesn't render in IE11 and below.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template: https://jsfiddle.net/reactjs/69z2wepo/).

  • Build React app with Webpack
  • Launch IE11 or below (not an emulator)
  • You will see a blank screen or half-compiled React app with the following error:
    24f8f6e8-afde-11e6-9a6f-a3cc6355f55c

What is the expected behavior?

  • To render as it does in Chrome, Firefox, etc.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
We've temporarily shrink-wrapped our dependencies so that we can continue to serve our app. We're starting to believe that it's coming from a dependency that react, apollo or webpack may be relying on...

Shrink-wrapped versions of our dependencies (left is the new one that's broken and the right one is the old one that continues to work across all browsers) https://www.diffchecker.com/SyaJUcsk

@aweary
Copy link
Contributor

aweary commented Nov 22, 2016

@FarhadG thanks for the report. Can you try to reproduce the error in dev? A diff of dependencies isn't too useful alone, unfortunately.We'd need a reproducible test case or a stack trace to try and narrow down the root cause here.

@FarhadG
Copy link
Author

FarhadG commented Nov 22, 2016

Thanks for the quick response, @aweary .

Did you want me to compile the app in development mode and test or start the webpack server in dev mode (i.e. hot reloading, etc.)

@gaearon
Copy link
Collaborator

gaearon commented Nov 22, 2016

You will see a blank screen or half-compiled React app with the following error:

Have you tried following the link in that error? It should include the information explaining why the error happened.

@FarhadG
Copy link
Author

FarhadG commented Nov 22, 2016

I did, @gaearon. It didn't make sense why it would work in Chrome and Firefox but not in IE11 and below. Thoughts?

@gaearon
Copy link
Collaborator

gaearon commented Nov 22, 2016

Maybe you enabled babel-plugin-react-inline-elements. It requires a Symbol polyfill and won't work without it. See #5138.

@FarhadG
Copy link
Author

FarhadG commented Nov 22, 2016

Going to give this a try, @gaearon, however, it's baffling that it's been working all along until a few days ago.

@aweary
Copy link
Contributor

aweary commented Nov 22, 2016

Did you want me to compile the app in development mode and test or start the webpack server in dev mode (i.e. hot reloading, etc.)

Either way, as long as React is not being built for production. This should at least give us a better idea of where the issue is occurring.

@FarhadG
Copy link
Author

FarhadG commented Nov 22, 2016

Looked through our codebase and we were not explicitly using babel-plugin-react-inline-elements nor were any of our configurations. Thanks for the suggestion, @gaearon.

@FarhadG
Copy link
Author

FarhadG commented Nov 22, 2016

So, we served our app in development and it appears to work, consistently, yet when we bundle in production, we see the same result. Let me know what information would be useful for us to help track this issue down, @aweary.

@gaearon
Copy link
Collaborator

gaearon commented Nov 22, 2016

@FarhadG Are you absolutely confident? Like maybe you use a preset that "optimizes" React which might include another preset, which might ultimately include that plugin.

@nhunzaker
Copy link
Contributor

nhunzaker commented Nov 22, 2016

@FarhadG I hit this on my current project and had to include the Symbol polyfill. I do this by adding a polyfills.js to my entry point that looks like:

/**
 * Place any polyfills here. This project uses core-js:
 * https://github.com/zloirock/core-js
 *
 * ES6:
 * https://github.com/zloirock/core-js/tree/master/es6
 */

//...

// We need Symbol support for some React optimizations
require('core-js/modules/es6.symbol')

Edit: We use the babel-preset-react-optimize package

@FarhadG
Copy link
Author

FarhadG commented Nov 22, 2016

That was our original idea after your suggestion, @gaearon. I followed these particular presets:

{
  "presets": ["es2015", "react", "stage-0"],
  "plugins": ["react-hot-loader/babel"]
}

... and didn't see them requiring anything to do with the optimization plugins.

Just gave it a try, for trying's sake, @nhunzaker, and the issue persists.

@tanepiper
Copy link

tanepiper commented Nov 30, 2016

I'm having the same issue. However I have two apps - one running 15.1.0 and one running 15.4.0, on a more recent update path.

https://www.votesforschools.com/ (15.1.0)
https://admin.votesforschools.com/ (15.4.0)

In each case in IE11 the exception is this:

https://facebook.github.io/react/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7B%24%24typeof%2C%20type%2C%20key%2C%20ref%2C%20props%2C%20_owner%7D&args[]=

Which outputs:

Objects are not valid as a React child (found: object with keys {$$typeof, type, key, ref, props, _owner}).

However this is only happening in deployed production. If I do a production build locally and serve it from Python SimpleHTTPServer this exception does not trigger.

I just want to report this, but as of tomorrow I'm rolling off this project as I'm starting a new job in the new year so I won't have access to the source code after this.

These are the only babel plugins being used (this is from our www config, admin is again slightly different)

"babel-core": "^6.10.4",
"babel-eslint": "^6.1.0",
"babel-loader": "^6.2.4",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-react-transform": "^2.0.2",
"babel-plugin-transform-class-properties": "^6.10.2",
"babel-plugin-transform-runtime": "^6.9.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-react": "^6.5.0",
"babel-preset-stage-0": "^6.5.0",
"babel-register": "^6.9.0",
"babel-runtime": "^6.9.2",

Update 1: In IE now getting an exception box on our dev environment (but not on production itself). Full text is:

Line: 213
Error: Objects are not valid as a React child (found: object with keys {$$typeof, type, key, ref, props, _owner, _store}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of `CoreLayout`.

On Production it's just the above one, without the mention of CoreLayout (which is just the app wrapper that called ReactDOM.render)

Update 2:

I've done the above with the polyfill. I have checked in the console and Symbol is available however I am still getting this error

Update 3:

Checked the node_modules folder, babel-plugin-react-inline-elements is not included anywhere so for me not linked to that

Update 4:

One project was causing a bit of a red herring.

The project that is currently running on React 15.1.0 has had no dependency updates since October in the package.json file, however packages are marked with the caret ^ symbol - so when running on the CI that means it was updating to the major version anyway.

I've changed this to tilde version locking (i.e. ~ on versions) and it resolved the issue for that project.

I've rolled back the second project to 15.3.2 and it's also working fine now.

@gaearon
Copy link
Collaborator

gaearon commented Nov 30, 2016

We'll need a complete project reproducing this to investigate.

@gaearon gaearon added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Nov 30, 2016
@FarhadG
Copy link
Author

FarhadG commented Nov 30, 2016

Thanks for including your debugging strategies, @tanepiper. Here's what we did in trying to figure out what the problem is:

  • Disabled react-tap-event-plugin
  • Removed react-tap-event-plugin
  • Reverted react-tap-event-plugin from v2.x to v1.0.0
  • Launched the app in development mode in IE11 and realized that it's something to do with webpack building our react app in production mode
  • Installed dependencies and built the app with various node versions: v5.5.0, v6.3.0, v.6.6.0
  • Rolled back many weeks which helped us understand that it wasn't something that we introduced but rather a dependency
  • Locked down all dev-dependencies to ensure that it's not something with one of our building dependencies
  • Locked down all dependencies to ensure it's not one of our explicit dependencies
  • Disabled shrinkwrap and locked our package.json in accordance with our successful npm-shrinkwrap.json, which helped us understand that it's a sub dependency
  • Shrink-wrapped a set of node_modules that we knew to work and diffed them against the broken ones to help us understand which dependencies it could potentially be (as noted in our issues)
  • Shrink-wrapped only our dependencies and not our dev-dependencies which showed us that it's most likely an issue from one of our dependencies as our ETE environments were successful when installing from a npm-shrinkwrap.json that contained only locked down our dependencies
  • Tried the several suggestions from the issues noted above:
    • Ensuring we were not using babel-plugin-react-inline-elements
    • Ensuring we were not using babel-preset-react-optimize
    • Tried the require('core-js/modules/es6.symbol') polyfill

@tanepiper
Copy link

@gaearon See updates above - rolled back to 15.3.2 and it's working so it's a recent change. Also turns out the CI was pulling React 15.4 anyway instead of 15.1 due to incorrect package.json config.

I will attempt to see if I can draw out a reproducible case for this but digging in a little bit it looks like whatever generates children for https://github.com/facebook/react/blob/master/src/shared/utils/traverseAllChildren.js is passing an object, not an array and that's what is triggering this exception.

@gaearon
Copy link
Collaborator

gaearon commented Nov 30, 2016

The problem is that React doesn't "recognize" its own element. This likely happens because of the failed $$typeof check. Somehow react and react-dom no longer "agree" on the $$typeof value which should be typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103.

This might mean that react and react-dom somehow get different results when testing for Symbol polyfill. For example if you load a polyfill after react initializes but before react-dom does, you might get this issue.

To debug it further I recommend finding this fragment in your bundle:

var r="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103;

You should see it two times (once from react and once from react-dom):

screen shot 2016-11-30 at 19 01 14

screen shot 2016-11-30 at 19 01 00

Try adding logs of r value and see if they're different. If they are, you'd need to figure out why react and react-dom get different values when checking for existence of Symbol.

The reason this is new in 15.4.0 is because there only used to be one version of this code, but now it's in both packages (intentionally).

@ghost
Copy link

ghost commented Dec 2, 2016

Update:

A coworker was able to find a workaround that involved removing the ReactDOM import from inside the .jsx file and instead listing it under the plugins section of webpack.config.js.

Original File Contents

webpack.config.js

plugins: [
    new webpack.ProvidePlugin({
      i18n: "i18next",
      '_': "lodash",
      'numeral': "numeral",
      React: "react"
    })
  ],

routes.jsx

import 'babel-polyfill';
import {render} from 'react-dom';
//**** snip  ***
ReactDOM.render(routes, document.getElementById('main'));

Updated Files

webpack.config.js

    new webpack.ProvidePlugin({
      i18n: "i18next",
      '_': "lodash",
      'numeral': "numeral",
      React: "react",
      ReactDOM: "react-dom"
    })
  ],

routes.jsx

import 'babel-polyfill';
//snip
ReactDOM.render(routes, document.getElementById('main'));

While this works, I still would like to get to the root cause. For the record, here is what our devDependencies looks like:

"devDependencies": {
    "alt": "^0.18.6",
    "babel-core": "^6.18.2",
    "babel-loader": "^6.2.8",
    "babel-plugin-transform-es2015-classes": "^6.18.0",
    "babel-polyfill": "^6.16.0",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "babel-preset-stage-2": "^6.18.0",
    "block-ui": "^2.70.1",
    "chai": "^3.5.0",
    "classnames": "^2.2.5",
    "css-loader": "^0.26.0",
    "enzyme": "^2.6.0",
    "flux": "^3.1.0",
    "history": "^4.4.0",
    "i18next": "^4.1.0",
    "json-loader": "^0.5.4",
    "karma": "^1.3.0",
    "karma-chai": "^0.1.0",
    "karma-chai-plugins": "^0.8.0",
    "karma-chrome-launcher": "^2.0.0",
    "karma-cli": "^1.0.1",
    "karma-mocha": "^1.3.0",
    "karma-mocha-reporter": "^2.2.1",
    "karma-sinon": "^1.0.5",
    "karma-sinon-chai-latest": "^0.1.0",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-webpack": "^1.8.0",
    "lodash": "^4.17.2",
    "moment": "^2.17.0",
    "mocha": "^3.1.2",
    "moment-timezone": "^0.5.9",
    "node-sass": "^3.13.0",
    "numeral": "^1.5.5",
    "react": "15.4.1",
    "react-addons-test-utils": "15.4.1",
    "react-bootstrap": "^0.30.7",
    "react-dom": "15.4.1",
    "react-router": "^3.0.0",
    "react-waypoint": "^4.1.0",
    "sass-loader": "^4.0.2",
    "sinon": "^1.17.6",
    "sinon-chai": "^2.8.0",
    "style-loader": "^0.13.1",
    "superagent": "^3.0.0",
    "vulcan": "git+ssh://git@github.com/mdsol/vulcan#2.2.2",
    "webpack": "^1.13.3"
  },

@gaearon
Copy link
Collaborator

gaearon commented Dec 2, 2016

Have you had a chance to try my suggestion from the comment above? #8379 (comment)

@damonbauer
Copy link

@gaearon I'm encountering this issue as well. I narrowed it down to some combination of react + babel-polyfill or babel-plugin-transform-runtime. I'll try to get a reduced test case going soon.

@gaearon
Copy link
Collaborator

gaearon commented Dec 2, 2016

It would really help if you could follow my suggestion above and let me know your findings.
Thanks!

@ghost
Copy link

ghost commented Dec 3, 2016

OK here is the change that I made in both spots:

var n="function"==typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103; 
debugger; console.log(n); e.exports=n}

Result from chrome:
image

Result from IE11
image

@gaearon
Copy link
Collaborator

gaearon commented Dec 3, 2016

Great! As you can see they are different. Can you now try to look into what makes Symbol exist in one case but not the other? Could it be a polyfill you are loading too late?

@damonbauer
Copy link

I fixed this by enforcing a load order in my webpack bundle:

  1. babel-polyfill
  2. react
  3. react-dom

Thanks for your patience and your infinite wisdom 😉 @gaearon

@gaearon
Copy link
Collaborator

gaearon commented Dec 5, 2016

I’m going to close this because it doesn’t appear to be a bug. It’s unfortunate this broke some apps but it’s very hard to protect against cases like this. In general my recommendation is that you should run any global polyfills before any other code in the bundle. Since polyfills are effectively modifying the environment, one should take care to do that consistently.

@gaearon gaearon closed this as completed Dec 5, 2016
@ssyrell
Copy link

ssyrell commented Oct 23, 2017

I ran into this when adding babel-polyfill to our react-redux app that was made using the asp.net core 2 template. This template splits up your webpack config into two separate configuration files (webpack.config.js and webpack.config.vendor.js). You need to modify the vendor array in webpack.config.vendor.js and put babel-polyfill at the top in order to get this to work.

I also had to fully clean up my environment (namely delete the wwwroot/dist folder) and rebuild the project in order for the changes to get properly picked up.

@dsteinbach
Copy link

dsteinbach commented Jan 27, 2018

This just started happening to me again in the last week in IE11 (ive resolved this same bug in the past using the above suggestions).

  "dependencies": {
    "babel-core": "^6.17.0",
    "babel-loader": "^6.2.5",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-runtime": "^6.15.0",
    "babel-polyfill": "^6.16.0",
    "babel-preset-es2015": "^6.14.0",
    "babel-preset-react": "^6.11.1",
    "babel-preset-stage-0": "^6.3.13",
    "babel-runtime": "^6.11.6",
    "better-npm-run": "0.0.11",
    "classnames": "^2.2.5",
    "css-loader": "^0.25.0",
    "currency-formatter": "^1.0.2",
    "debug": "^2.2.0",
    "exports-loader": "^0.6.3",
    "extract-text-webpack-plugin": "^1.0.0",
    "file-loader": "^0.9.0",
    "formsy-react": "^0.18.1",
    "fs-extra": "^0.30.0",
    "html-webpack-plugin": "^2.22.0",
    "imports-loader": "^0.6.5",
    "ip": "^1.1.2",
    "json-loader": "^0.5.4",
    "lodash": "^4.11.2",
    "moment": "^2.10.6",
    "node-sass": "^3.4.2",
    "normalize.css": "^4.1.1",
    "numeral": "^1.5.3",
    "pure-render-decorator": "^1.1.0",
    "react": "^15.0.0",
    "react-ab-test": "^2.0.1",
    "react-bootstrap": "^0.30.3",
    "react-cookie": "^1.0.5",
    "react-datetime": "^2.6.0",
    "react-document-meta": "^2.0.3",
    "react-dom": "^15.0.0",
    "react-redux": "^4.4.5",
    "react-router": "^2.8.0",
    "react-router-scroll": "^0.2.0",
    "react-select": "1.0.0-rc.1",
    "react-slick": "^0.14.3",
    "react-sticky": "^5.0.5",
    "react-telephone-input": "^3.5.0",
    "redux": "^3.6.0",
    "redux-thunk": "^2.0.0",
    "rimraf": "^2.5.4",
    "sass-loader": "^4.0.0",
    "seamless-immutable": "^6.1.0",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.6",
    "validator": "^5.2.0",
    "webpack": "^1.12.14",
    "whatwg-fetch": "^1.0.0",
    "yargs": "^5.0.0"
  },

The error:

SCRIPT5022: Objects are not valid as a React child (found: object with keys {$$typeof, type, key, ref, props, _owner, _store}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of 'RedBoxError'.
File: vendor.ab56ae7d3f092ad6e17f.js, Line: 1391, Column: 6

@mzahidriaz-tr
Copy link

Nothing worked for me either, changing the order of the polyfill or anything else.
What worked for me is adding this JS link in the index.html

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.15/browser-polyfill.min.js"></script>

After adding this I was successfully able to run the react app in IE 11

lukebarnard1 added a commit to element-hq/element-web that referenced this issue Apr 27, 2018
This is to avoid loading anything before loading the polyfill, otherwise
we risk loading dependencies (such as React) before it.

This was causing the compatibility page to fail somehow.

See facebook/react#8379

Fixes #6562
@agauti003
Copy link

Hello Guys I had similar issue but then in my index.js i used

<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script> and my issue was resolved.

@nicklayb
Copy link

nicklayb commented Sep 4, 2018

I have read all the comments and if I read correctly, both working solutions are either, eject the webpack config or add cdn package, just to support IE11?

@gaearon
Copy link
Collaborator

gaearon commented Sep 4, 2018

You don't need to add anything to webpack config.

@gaearon
Copy link
Collaborator

gaearon commented Sep 4, 2018

React 16 requires a few runtime JS features that are missing in IE11, but easy to add with polyfills.

See here for how to add them: https://reactjs.org/docs/javascript-environment-requirements.html

Just make sure you put those imports in the entry point of your application, before any other imports.

If this didn't help, you might be having the same problem as #8379 (comment). TLDR is that if you choose to polyfill Symbol (React doesn't require it), make sure this polyfill runs before both react and react-dom. So also put it before any other imports in the entry point file.

I'm going to lock to prevent further confusion since comments about webpack are already confusing people into ejecting, which is absolutely unnecessary for this.

But if you do have a custom webpack config then maybe your problem is similar to #8379 (comment) which provides a clue about how to fix it.

@facebook facebook locked as resolved and limited conversation to collaborators Sep 4, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests