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

[v2] IE11 throws Objects are not valid as a React child #7003

Closed
alexandernanberg opened this issue Aug 3, 2018 · 45 comments · Fixed by #9669
Closed

[v2] IE11 throws Objects are not valid as a React child #7003

alexandernanberg opened this issue Aug 3, 2018 · 45 comments · Fixed by #9669
Labels
type: maintenance An issue or pull request describing a change that isn't a bug, feature or documentation change

Comments

@alexandernanberg
Copy link
Contributor

Description

When visiting sites using v2 in IE11 React throws an error

Steps to reproduce

Visit https://next.gatsbyjs.org in IE11 and check the console

Expected result

No errors

Actual result

React throws this error;

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

Environment

  System:
    OS: macOS High Sierra 10.13.6
    CPU: x64 Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
    Shell: 5.3 - /bin/zsh
  Binaries:
    Node: 8.11.3 - ~/.nvm/versions/node/v8.11.3/bin/node
    Yarn: 1.9.2 - /usr/local/bin/yarn
    npm: 5.6.0 - ~/.nvm/versions/node/v8.11.3/bin/npm
  Browsers:
    Chrome: 68.0.3440.84
    Firefox: 61.0.1
    Safari: 11.1.2
  npmPackages:
    gatsby: ^2.0.0-beta.64 => 2.0.0-beta.67 
    gatsby-plugin-catch-links: ^2.0.2-beta.5 => 2.0.2-beta.5 
    gatsby-plugin-feed: next => 2.0.0-beta.4 
    gatsby-plugin-glamor: next => 2.0.0-beta.3 
    gatsby-plugin-google-analytics: next => 2.0.0-beta.3 
    gatsby-plugin-manifest: next => 2.0.2-beta.3 
    gatsby-plugin-netlify: next => 2.0.0-beta.5 
    gatsby-plugin-nprogress: next => 2.0.0-beta.4 
    gatsby-plugin-react-helmet: next => 3.0.0-beta.4 
    gatsby-plugin-sharp: next => 2.0.0-beta.7 
    gatsby-plugin-twitter: next => 2.0.0-beta.3 
    gatsby-remark-autolink-headers: next => 2.0.0-beta.5 
    gatsby-remark-code-repls: next => 2.0.0-beta.4 
    gatsby-remark-copy-linked-files: next => 2.0.0-beta.3 
    gatsby-remark-embed-snippet: next => 3.0.0-beta.3 
    gatsby-remark-images: next => 2.0.1-beta.9 
    gatsby-remark-prismjs: next => 3.0.0-beta.5 
    gatsby-remark-responsive-iframe: next => 2.0.0-beta.3 
    gatsby-remark-smartypants: next => 2.0.0-beta.3 
    gatsby-source-filesystem: next => 2.0.1-beta.10 
    gatsby-transformer-remark: next => 2.1.1-beta.5 
    gatsby-transformer-sharp: next => 2.1.1-beta.6 

File contents (if changed)

gatsby-config.js: N/A
package.json: N/A
gatsby-node.js: N/A
gatsby-browser.js: N/A
gatsby-ssr.js: N/A

@anantoghosh
Copy link
Contributor

This does not occur in the starter project and another project which I'm working on.
Is this gatsbyjs.org specific? Or do you have any other repo/site which has this issue?

@anantoghosh anantoghosh added the status: needs more info Needs triaging and reproducible examples or more information to be resolved label Aug 4, 2018
@alexandernanberg
Copy link
Contributor Author

No it's not gatsbyjs.org specific because I first noticed it when migrating reactjs.org (preview link) to v2. Here is the repo for that if you need it.

My best guess would be that polyfills aren't loaded correctly, like the Symbol polyfill which is required for React. Think I've seen this error before on a non-gatsby site and adding the correct polyfills solved that. Also I think the reason why you don't get any errors is because you might not use fragments or return arrays?

Here is an issue that might help facebook/react#8379

@anantoghosh
Copy link
Contributor

/cc @pieh @KyleAMathews @m-allanson

@stripeyjumper
Copy link
Contributor

stripeyjumper commented Aug 8, 2018

I worked around this by adding the babel polyfills as a webpack entry point in gatsby-node.js:

exports.onCreateWebpackConfig = ({
  stage,
  getConfig,
  actions: { replaceWebpackConfig }
}) => {
  switch (stage) {
    case 'build-javascript':
      // We want to include the babel polyfills before any application code,
      // so we're inserting it as an additional entry point.  Gatsby does not allow
      // this in "setWebpackConfig", so we have to use "replaceWebpackConfig"
      const config = getConfig();

      const app =
        typeof config.entry.app === 'string'
          ? [config.entry.app]
          : config.entry.app;

      config.entry.app = ['@babel/polyfill', ...app];
      replaceWebpackConfig(config);
  }
};

@KyleAMathews
Copy link
Contributor

I just did a build and the Symbol polyfill is in there

screenshot 2018-08-08 10 59 49

@alexandernanberg
Copy link
Contributor Author

Hmm could it be Map or Set that is missing then? Also noticed that the site doesn't work at all in IE11 when you run gatsby develop, same error though

@KyleAMathews
Copy link
Contributor

From reading facebook/react#8379 (comment) one possibility is that the polyfill is loading after React which could be happening since we're relying on Babel 7's polyfilling which adds polyfill imports as they're needed — which wouldn't actually be working since we don't run React through Babel.

Ah yeah, confirmation babel/babel#7335 (comment)

So we need to manually add the necessary polyfills to ensure they're run first.

@KyleAMathews
Copy link
Contributor

One way to do this is to a) add the polyfills directly at the top of production-app.js (our entry) and then b) in our webpack config, look at what browsers people are supporting — if they're not supporting ie11 or below then we remove those polyfills.

Thoughts?

Anyone want to tackle this?

@alexandernanberg
Copy link
Contributor Author

How would we be able to remove them in the webpack config though 🤔

I suppose you mean like this

// production-app.js
import '@babel/polyfill'
// or just the necessary polyfills
import 'core-js/es6/set'
import 'core-js/es6/map'

Then AFAIK there is no way to remove them, I could be wrong though

Huh strange, always though Symbol was needed for React but that might not the case https://reactjs.org/docs/javascript-environment-requirements.html

I could take this on, but unfortunately I won't have time until the weekend-ish. So if anyone else wanna grab this feel free to do so!

@KyleAMathews
Copy link
Contributor

We'd conditionally add https://webpack.js.org/plugins/ignore-plugin/

@alexandernanberg
Copy link
Contributor Author

Oh cool, didn't know you could do that!

@KyleAMathews
Copy link
Contributor

It's a neat trick :-)

@stripeyjumper
Copy link
Contributor

If the babel settings for babel-preset-env were changed to useBuiltIns: 'entry', would that cause babel to include the polyfills according to the browserslist settings?

That's what the docs suggest, but I haven't tried it.
https://babeljs.io/docs/en/next/babel-preset-env.html#usebuiltins

@alexandernanberg
Copy link
Contributor Author

Weird, I can no longer reproduce this in the production build, everything seems to be working now 🤷‍♂️

Still get errors in development though but I think this is intended right?

// .babel-preset.js
  const browserConfig = {
    useBuiltIns: false,
    targets: {
      browsers: PRODUCTION
        ? [`last 4 versions`, `safari >= 7`, "ie >= 9"]
        : [`last 2 versions`, `not ie <= 11`, `not android 4.4.3`],
    },
  }

@KyleAMathews
Copy link
Contributor

Huh that is weird!

That bit of code is for compiling the Gatsby owned code. For compiling your code, this is where babel is setup

let targets
if (stage === `build-html`) {
targets = { node: `current` }
} else {
targets = { browsers: browserslist }
}
// Presets
actions.setBabelPreset({
name: `@babel/preset-env`,
stage,
options: {
loose: true,
modules: false,
useBuiltIns: `usage`,
targets,
},

@alexandernanberg
Copy link
Contributor Author

Oh I see!

Seems like I can't really figure this one out to be honest... it should technically work if I add this right?

// my-gatsby-site/.cache/app.js
import 'core-js/es6/map'
import 'core-js/es6/set'
...

If I add a console.log that get printed so I'm not really sure what's happening

@jrskerritt
Copy link

I'm seeing this issue too after recently upgrading to v2. Here's some relevant snippets that might help y'all:

package.json

"dependencies": {
    "axios": "0.18.0",
    "babel-runtime": "6.26.0",
    "intersection-observer": "0.5.0",
    "prop-types": "15.6.2",
    "react": "16.4.2",
    "react-dom": "16.4.2",
    "react-dropdown": "1.5.0",
    "react-helmet": "5.2.0",
    "react-tabs": "2.2.2"
  },
  "devDependencies": {
    "aws-sdk": "2.283.1",
    "babel-core": "6.26.3",
    "babel-eslint": "8.2.6",
    "babel-jest": "23.4.2",
    "babel-loader": "7.1.5",
    "babel-polyfill": "6.26.0",
    "babel-preset-env": "1.7.0",
    "babel-preset-es2015": "6.24.1",
    "babel-preset-react": "6.24.1",
    "babel-preset-stage-0": "6.24.1",
    "enzyme": "3.3.0",
    "enzyme-adapter-react-16": "1.1.1",
    "eslint": "4.18.1",
    "eslint-config-payscale": "1.0.3",
    "eslint-plugin-react": "7.10.0",
    "eslint-teamcity": "1.4.0",
    "gatsby": "2.0.0-beta.93",
    "gatsby-module-loader": "2.0.0-alpha.3",
    "gatsby-plugin-google-tagmanager": "2.0.0-beta.3",
    "gatsby-plugin-react-helmet": "2.0.11",
    "gatsby-plugin-sass": "2.0.0-beta.6",
    "gatsby-source-aem": "1.8.8",
    "gatsby-source-filesystem": "2.0.1-beta.10",
    "gatsby-source-wordpress": "2.0.93",
    "gatsby-transformer-json": "2.1.1-beta.4",
    "jest": "23.4.2",
    "jest-teamcity-reporter": "0.9.0",
    "node-sass": "4.9.2",
    "react-test-renderer": "16.4.1"
  }

gatsby-browser.js

const getPolyfills = () => {
  if (!('IntersectionObserver' in window)) {
    require('intersection-observer');
  }
};

exports.onClientEntry = () => {
  getPolyfills();
};

gatsby-config.js

plugins: [
    'gatsby-plugin-sass',
    'gatsby-plugin-react-helmet',
    'gatsby-transformer-json',
    // other plugins that aren't relevant

Nothing in gatsby-node.js besides createPages

Windows 10, node 8.9.4

@Chuloo Chuloo added type: maintenance An issue or pull request describing a change that isn't a bug, feature or documentation change and removed status: needs more info Needs triaging and reproducible examples or more information to be resolved labels Aug 22, 2018
asudoh added a commit to asudoh/carbon-website-gatsby that referenced this issue Sep 19, 2018
Gatsby's default .babelrc is configured in a manner that automatically imports Babel polyfills
based on usage of corresponding API.

Such Babel polyfills are loaded after RHL imports `react` module and before page bundle generated by Gatsby
imports `react-dom` module, which causes `react` and `react-dom` referring to different Symbol class object,
triggering gatsbyjs/gatsby#7003.

Refs carbon-design-system#24.
asudoh added a commit to asudoh/carbon-website-gatsby that referenced this issue Sep 19, 2018
Gatsby's default `.babelrc` is configured in a manner that automatically imports Babel polyfills
based on usage of corresponding API.

Such Babel polyfills are loaded after RHL imports `react` module and before page bundle generated by Gatsby
imports `react-dom` module, which causes `react` and `react-dom` referring to different `Symbol` class object,
triggering gatsbyjs/gatsby#7003.

Refs carbon-design-system#24.
@pungggi
Copy link

pungggi commented Sep 21, 2018

I am getting this error on the production build in V1..
develop works fine..

upgrading to V2 works in production but not in develop

@sarahannnicholson
Copy link
Contributor

I was able to resolve the error on localhost by following @stripeyjumper's 2nd comment #7003 (comment) and adding a bit more.

  1. npm i @babel/polyfill --save-dev
  2. Created a .babelrc file in the project root and pasted in the sample file from the gatsby website https://www.gatsbyjs.org/docs/babel/#how-to-use-a-custom-babelrc-file
  3. Changed line 8 from useBuiltIns: "usage" to useBuiltIns: "entry"
  4. Added import "@babel/polyfill" at the top of gatsby-browser.js
  5. run gatsby develop to view http://localhost:8000/ in IE

I tried @stripeyjumper's 1st comment #7003 (comment) but I still see an error in IE11 in production

Expected ':' 
TypeError: Object doesn't support this action 

I am not sure why this workaround works locally, or how to get it to work on production.

@pieh
Copy link
Contributor

pieh commented Oct 15, 2018

I've just checked www.gatsbyjs.org on IE11 and it works (built with gatsby@2.0.21. So we probably need some reproductions to pinpoint where and why this is happening and determine if this is something we can try to fix

@AlmeroSteyn
Copy link
Contributor

@pieh I am getting the issue only when I try to insert a component that is meant to be functional at runtime. If the page is purely "static" I do not see the issue.

I will see if I can reproduce with code that I can share at this stage.

@AlmeroSteyn
Copy link
Contributor

@pieh I am unable to create a simple reproduction of the issue. Tried the usual suspects but they are not creating the issue.

From the issue I thought this was a more general problem.

Will need to completely break apart the component where this is going wrong. So will dig into that later.

@DSchau DSchau added status: needs more info Needs triaging and reproducible examples or more information to be resolved status: needs reproduction This issue needs a simplified reproduction of the bug for further troubleshooting. and removed status: inkteam to review labels Oct 15, 2018
@sarahannnicholson
Copy link
Contributor

@AlmeroSteyn I found that

Adding the new Webpack config to gatsby-node.js does nothing for me.

Didn't work for me as well.

You mentioned

I cannot even get the dev environment started in IE

Myself and others have had success running locally by following these instructions #7003 (comment) . Have you given it a try?

@AlmeroSteyn
Copy link
Contributor

@sarahannnicholson I dunno what I did the previous time around and which one of the fixes for IE11 dev mode I tried but yours works. Thank you!!!

I now have the same situation as you, works in dev, not in prod.

Gonna see this morning if I can narrow it down adding some realtime functionality works and others don't.

@AlmeroSteyn
Copy link
Contributor

@pieh @DSchau I seem to have pinpointed the offending code.

It seems that this happens using a child render prop and then combining a props spread operator with setting another prop from the parameter of the render function.

The following code reproduces the issue on my side:

import React from 'react'

class TestRenderer extends React.Component {
  render() {
    return this.props.children('testValue')
  }
}

class TestAcceptor extends React.Component {
  render() {
    return (
      <div>
        {this.props.t}
        {this.props.s}
      </div>
    )
  }
}

const Combinator = props => (
  <TestRenderer>{t => <TestAcceptor t={t} {...props} />}</TestRenderer>
)

export default Combinator

If I import and use this in my index.js file, it throws the following errors on console in IE11 when using the uglified code:

SCRIPT1003: Expected ':'

and

Unhandled promise rejection TypeError: Object doesn't support this action

This is the exact same scenario that also triggers it in my production application.

I have also tried the following scenarios and they all worked fine:

const Combinator = props => (
  <TestRenderer>{t => <TestAcceptor {...props} />}</TestRenderer>
)
const Combinator = props => (
  <TestRenderer>{t => <TestAcceptor t={t} />}</TestRenderer>
)
const Combinator = props => (
  <TestAcceptor t="testValue" {...props} />
)

So it really seems that this only happens in a render prop.

I hope this helps as it would be really great to get this fixed.

Note: The same component works fine without console errors in the production build of create-react-app v2.

@pieh
Copy link
Contributor

pieh commented Oct 16, 2018

@AlmeroSteyn Would you be able to apply changes from #9135 to your gatsby (in node_modules/gatsby/dist/utils/webpack-utils.js - it will be transpiled, so might be hard to read - but you should find terserOptions there) and see if it fixes it? This PR port setup from create-react-app, so possibly this is the problem we have.

@AlmeroSteyn
Copy link
Contributor

@pieh Oh that fixes it alright! Awesome!

If I apply those settings, my production app works with minification and has a clean console.

Please merge :-)

@iaindurie
Copy link

I had the same issues as described above in IE11 on v2, and installing gatsby-plugin-polyfill-io fixed it for me. It now runs fine locally and builds fine too.

@rtm619
Copy link

rtm619 commented Oct 16, 2018

@pieh I applied the changes from PR #9135 too and it definitely fixed it for me as well. My app's working fine in IE 11 with no console errors. :)

@pieh
Copy link
Contributor

pieh commented Oct 16, 2018

Linked PR was merged and published in gatsby@2.0.25 so please update ;)

@AlmeroSteyn
Copy link
Contributor

@pieh Thanks you! Test drove it this morning and all good now. Thanks for jumping on it so quickly.

@souporserious
Copy link

Pinging @DSchau. We talked yesterday about this error still being thrown in development builds. It looks it might be caused by browsersList not getting set properly in dev mode. Maybe warrants this issue being reopened, please let me know and I can file a new issue.

@DSchau
Copy link
Contributor

DSchau commented Nov 2, 2018

@thetre97 👋 Working on this now!

@DSchau DSchau reopened this Nov 2, 2018
@kakadiadarpan kakadiadarpan removed status: needs more info Needs triaging and reproducible examples or more information to be resolved status: needs reproduction This issue needs a simplified reproduction of the bug for further troubleshooting. labels Nov 9, 2018
@antoinerousseau
Copy link
Contributor

antoinerousseau commented Jan 8, 2019

I still have this issue with Gatsby v2.0.76 in IE11 (thrown by react-dom).

Edit: conditionally loading polyfill.io features in onClientEntry like this does not even fix the issue:

export const onClientEntry = () =>
  new Promise((resolve, reject) => {
    const features = []

    const isIE = /MSIE|Trident/.test(navigator.userAgent)

    let src = 'https://cdn.polyfill.io/v2/polyfill.min.js?callback=__polyfillCallback'

    if (!isIE) {
      if (!('Set' in window)) {
        features.push('Set')
      }

      if (!('Map' in window)) {
        features.push('Map')
      }

      if (!('Intl' in window)) {
        features.push('Intl.~locale.fr')
        features.push('Intl.~locale.en')
        features.push('Intl.~locale.es')
      }

      if (!('fetch' in window)) {
        features.push('fetch')
      }

      if (!('URL' in window && 'URLSearchParams' in window)) {
        features.push('URL')
      }

      if (!features.length) {
        resolve()
        return
      }

      src += `&features=${features.join(',')}`
    }

    window.__polyfillCallback = resolve
    const tag = document.createElement('script')
    tag.src = src
    tag.async = true
    tag.onerror = reject
    document.head.appendChild(tag)
  })

I see https://cdn.polyfill.io/v2/polyfill.min.js?callback=__polyfillCallback being loaded in IE11 but the error still shows up.

The only way I found is:

setHeadComponents([<script src="https://cdn.polyfill.io/v2/polyfill.min.js" />])

But it means it will always be loaded: I would like to avoid it in modern browsers!

@cjk
Copy link

cjk commented Apr 9, 2019

@antoinerousseau 's solution - though somewhat 'unconventional' - was so far the only way for me to get an IE11 compatible site running. Hope a better solution will be available soon (or IE go away, whichever happens first).

@1-800-jono
Copy link
Contributor

I was able to resolve the error on localhost by following @stripeyjumper's 2nd comment #7003 (comment) and adding a bit more.

  1. npm i @babel/polyfill --save-dev
  2. Created a .babelrc file in the project root and pasted in the sample file from the gatsby website https://www.gatsbyjs.org/docs/babel/#how-to-use-a-custom-babelrc-file
  3. Changed line 8 from useBuiltIns: "usage" to useBuiltIns: "entry"
  4. Added import "@babel/polyfill" at the top of gatsby-browser.js
  5. run gatsby develop to view http://localhost:8000/ in IE

I tried @stripeyjumper's 1st comment #7003 (comment) but I still see an error in IE11 in production

Expected ':'
TypeError: Object doesn't support this action
I am not sure why this workaround works locally, or how to get it to work on production.

Been trying to make gatsby develop work in IE 11 using this but still not working.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: maintenance An issue or pull request describing a change that isn't a bug, feature or documentation change
Projects
None yet