React Invariant Violation / Minified Exception on iOS 8 with Webpack + Babel

TL;DR

Check out this gist to see the bug.

I ran into a head-scratcher over the weekend that I needed document, because I spent a few more hours than I wanted to trying to see why a deployed project wasn't working at all on iOS 8.4.

My project is using react, webpack, and babel. One of the babel plugins I'm using is babel-plugin-transform-react-inline-elements which transforms react elements to increase performance in production.

I'm also using the babel-polyfill (which includes the core-js shim) to polyfill some features like Symbols.

The project was working fine locally on iOS 8, but when deployed I was getting an error from react.

Error: Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.

If I removed the babel-polyfill, the error went away. The problem was I needed the babel-polyfill especially on iOS 8 where there is no Symbol. I also tried just loading core-js/shim or just core-js/es6/symbol but the error was still happening. Here's a way stripped down version of my main JS file which was causing the error:

// The error goes way with no polyfill, but I need the polyfill
import 'babel-polyfill';

import React from 'react';
import DOM from 'react-dom';

DOM.render(
  <div>hey everybody</div>,
  document.getElementById('root')
);

Next, I removed the webpack define plugin so it was no longer replacing process.env.NODE_ENV so I could see what the unminified error was:

Invariant Violation: ReactDOM.render(): Invalid component element. This may be caused by unintentionally loading two independent copies of React.

I had a feeling that I wasn't actually loading two different copies of react, so I kept digging. It was then that I remembered I had some babel plugins turned on in production only. My .babelrc looked like this:

{
  "presets": [
    "react",
    "es2015"
  ],
  "env": {
    "production": {
      // Yay! Removing this plugin fixes it!
      "plugins": [
        "transform-react-inline-elements"
      ]
    }
  }
}

Once I disabled the transform-react-inline-elements plugin the error went away. Since this plugin is only used for performance improvements, I decided that working on iOS 8 was more important.

I put together a full gist of the bug to make it easier to reproduce. I still don't know exactly why this error is happening, but I plan on trying to report it to the relevant projects to see if it can be tracked down and fixed. The main lessons I learned though: