Search code examples
requirejspolyfillswirejs

Preload polyfill libraries using requirejs


I am creating a wirejs app using requirejs. For IE 8 I am using polyfills: cujo/poly js library and require this lib be preloaded before wirejs is loaded.

If I used curl as the AMD loader, as per the documentation, I have following option available:

curl({ preloads: [ "poly" ] });

What works for me is:

// in index.html

<script data-main="js/app" src="js/lib/require.js"></script>

// in js/app.js

define(function(){
   // set configuration options
   requirejs.config({// set config with paths});

   // require the library and HOPE it will load before
   // everything else!
   require(['poly']);

});

This document recommends using shim config for this purpose. However, I haven't been able to figure out how. Some of the things I tried:

// DID NOT WORK!!
requirejs.config({

....
"shim": {
   "poly": {
     "exports": "poly"
    }
 }
});

Is there a better way to approach this?

Any help appreciated!...thanks for your time!


Solution

  • I do use RequireJS together with polyfills, but I don't use RequireJS to load them. The goal of a polyfill is to make a browser which lacks feature X look as if it does in fact have feature X. I prefer a setup in which all the code I run (with the exception of the polyfills themselves) runs with the polyfills already loaded so that the code runs with the same set of features available to it, no matter what browser runs the code. So I want my polyfills loaded before RequireJS too.

    But if we ignore this preference, could RequireJS be used to load the polyfills? Yes, but RequireJS won't make it easy. There's no trivial way to tell RequireJS "this body of code must be loaded before you load anything else", which is what you'd want for polyfills. What you'd have to do is manually invoke require so that your polyfills are loaded first. Your index.html could be something like:

    <script>
        require = {
           // Your config.
           //
           // Setting a global require before loading RequireJS is one way to give it
           // a config.
        };
    </script>
    <script src="js/lib/require.js"></script>
    <script>
        // No data-main above...
        //
        // This double require ensures that the polyfills are loaded first.
        require(["poly"], function () {
            require(["js/app"]);
        });
    </script>
    

    js/app.js becomes:

    define(function(){
        // whatever...
    });
    

    In a large application where there may be multiple entry points other than js/app, you have to use the double require like above every time you want to load a module from outside a RequireJS module to ensure that the polyfills are loaded first.