Ian Obermiller

Part time hacker, full time dad.

Conditionally Load Intl Polyfill with Webpack

Posted

So, you want to use the new JavaScript Internationalization API, Intl? Perhaps you even want to use it with the awesome React Intl library. Browser support is okay, but if you want to support <IE11 and any version of Safari you'll have to use a polyfill. Unfortunately, the polyfill is pretty large if you use the full build with all languages, clocking in at ~150k minified and gzipped. Wouldn't it be great if we could set up our JavaScript app to download the Intl library only if the browser needs the polyfill? Fortunately, this is really easy to do using webpack.

1. Install intl

npm install --save intl

2. Modify app's entry point

Before, our app's entry point using React was simple and synchronous:

var React = require('react');
var App = require('./App');

React.render(<App />, document.body);

Now, we need to put all our initialization code into a function, and wait to invoke the function until the polyfill is loaded:

function run() {
  var React = require('react');
  var App = require('./App');

  React.render(<App />, document.body);
}

// Check if polyfill required
if (!window.Intl) {
  // Webpack parses the inside of require.ensure at build time to know that intl
  // should be bundled separately. You could get the same effect by passing
  // ['intl'] as the first argument.
  require.ensure([], () => {
    // Ensure only makes sure the module has been downloaded and parsed.
    // Now we actually need to run it to install the polyfill.
    require('intl');

    // Carry on
    run();
  });
} else {
  // Polyfill wasn't needed, carry on
  run();
}

That's all there is to it. Webpack takes care of splitting the bundle and downloading the polyfill on require.ensure! This method should work with all kinds of polyfills, and keeps your app lean for modern browsers yet working in the rest. For more information, see the webpack documentation for code splitting.