gatsby: [v2] IE11 throws Objects are not valid as a React child

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

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 5
  • Comments: 45 (34 by maintainers)

Commits related to this issue

Most upvoted comments

The solution for my GatsbyJS [V2] broken production build for IE11 was;

$ npm i --save @babel/polyfill

then…

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);
  }
};

then…

$ gatsby build

Cheers @stripeyjumper

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!

@KyleAMathews Sorry to be an utter pain here. Don’t want to be THAT developer but I have no idea currently how to fix this issue aside from turning off uglification.

The project I am using Gatsby in for an accessibility company, so using Gatsby in our own products would be a great push for the accessibility possibilities of the tool itself.

However, not working in IE11 could very well be a deal breaker. Yes, I can get it working without uglification but that almost doubles the JS payload size.

If this is in the pipeline to be fixed, or there is another, less hacky fix, it is all good. I just need to know.

If I had any idea exactly which part of the code was killing IE I would really have been more helpful but I cannot even get the dev environment started in IE, so that leaves cryptic messages and tons of minified code to try and wade through.

If there is anything I can do to help please let me know.

I was able to resolve the error on localhost by following @stripeyjumper’s 2nd comment https://github.com/gatsbyjs/gatsby/issues/7003#issuecomment-411388013 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 https://github.com/gatsbyjs/gatsby/issues/7003#issuecomment-411351268 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.

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.

Ok I have been getting the same issues on my site.

However I have tried all the above but only --no-uglify fixes it for me in IE.

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

Is there any plan going ahead for how to do this without disabling uglification?

Would really appreciate this.

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

@AlmeroSteyn Would you be able to apply changes from https://github.com/gatsbyjs/gatsby/pull/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.

From reading https://github.com/facebook/react/issues/8379#issuecomment-264858787 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 https://github.com/babel/babel/issues/7335#issuecomment-363209373

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

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);
  }
};

@thetre97 👋 Working on this now!

@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 😃

@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.

Yes, I tried --no-uglify with gatsby build too and it works in IE 11.

I tried @sarahannnicholson’s approach and can confirm that when running gatsby develop, there are no console errors in IE11, but when running gatsby build, I get the same errors as @sarahannnicholson.

But I don’t get any errors in IE11 when I run gatsby build --no-uglify