What is the correct way to load polyfills and shims with Browserify

romeovs picture romeovs · Jan 10, 2015 · Viewed 11k times · Source

I'm building a web app and I'm getting to know and love Browserify. One thing has bugged me though.

I'm using some ES6 features that need to be shimmed/polyfilled in older browsers such as es6-promise and object-assign (packages on npm).

Currently I'm just loading them into each module that needs them:

var assign  = require('object-assign');
var Promise = require('es6-promise');

I know this is definitely not the way to go. It is hard to maintain and I would like to use the ES6 features transparently instead of having to "depend" on them via requires.

What's the definitive way to load shims like these? I've seen several examples around the internet but they're all different. I could:

  • load them externally:

    var bundle = browserify(); 
    bundle.require('s6-promise');
    // or should I use it bundle.add to make sure the code is runned???
    

    The problem I have here is that I don't know which order the modules will be loaded in in the browser. So the polyfilling might not have happened yet at call sites that need the polyfilled functionality.

    This has the additional downside that backend code cannot benefit from these polyfills (unless I'm missing something).

  • use browserify-shim or something similar. I don't really see how this would work for ES6 features.

  • manually set up the polyfilling:

    Object.assign = require('object-assign');
    

Answer

caridy picture caridy · Mar 10, 2015

Don't require polyfills in your modules, that's an anti-pattern. Your modules should assume that the runtime is patched (when needed), and that should be part of the contract. A good example of this is ReactJS, where they explicitly define the minimum requirement for the runtime so that the library can work: http://facebook.github.io/react/docs/working-with-the-browser.html#browser-support-and-polyfills

You could use a polyfill service (e.g.: https://cdn.polyfill.io/) to include an optimized script tag at the top of your page to guarantee that the runtime is patched correctly with the pieces you need, while modern browsers will not get penalized.