Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading jQuery, Underscore and Backbone using RequireJS 2.0.1 and shim

I am experimenting a little bit with RequireJS 2.0.1. My goal is to load correctly jQuery, Underscore and Backbone. From the original RequireJS doc I discovered that the author J. Burke added (to this new release) a new config option called shim.

Then I wrote this stuff down here:

index.html

<!DOCTYPE html> <html>     <head>         <title>Testing time</title>         <script data-main="scripts/main" src="scripts/require.js"></script>     </head>     <body>         <h1>Testing time</h1>     </body> </html> 

scripts/main.js

requirejs.config({     shim: {         'libs/jquery': {             exports: '$'         },         'libs/underscore': {             exports: '_'         },         'libs/backbone': {             deps: ['libs/underscore', 'libs/jquery'],             exports: 'Backbone'         }     } });   define(     ['libs/jquery', 'libs/underscore', 'libs/backbone'],      function (jQueryLocal, underscoreLocal, backboneLocal) {         console.log('local', jQueryLocal);         console.log('local', underscoreLocal);         console.log('local', backboneLocal);         console.log('global', $);         console.log('global', _);         console.log('global', Backbone);     } ); 

Everything seems to work quite fine, but I have the feeling that I'm missing something, I know that there are AMDed version of jQuery and Underscore but if the setup is so simple I don't understand why I should use them.

So, is this setup right or I'm missing something?

like image 919
vrde Avatar asked Jun 02 '12 23:06

vrde


2 Answers

You only need to use "shim" config if the library does not already call define() to declare a module. jQuery does this already, so you can remove that from the shim config. The above code will work as is, but the exports shim config for jQuery will be ignored since jQuery will call define() before the shim work is done.

The downsides with the shim vs having the script call define() to define a module:

  1. It is less portable/reliable: every developer needs to do the shim config, and keep track of library changes. If the library author does it inline in the library, everyone gets the benefits more efficiently. The code templates at umdjs/umd can help with that code change.

  2. Less optimal code loading: shim config works by loading shim deps before loading the actual library. So it is a bit more sequential loading than parallel. It is faster if all scripts can be loaded in parallel, which is possible when define() is used. If you do a build/optimization for final deployment and combine all the scripts into one script, then this is not really a downside.

like image 137
jrburke Avatar answered Sep 21 '22 21:09

jrburke


What you are doing is correct, but jQuery does not need to be in the shim config because it exports an AMD (Asynchronous Module Definition) module. Underscore removed its support for AMD / Require.js quickly after adding it, see: Why underscore.js removed support for AMD

Shim is intended as a convenience for using libraries that do not export an AMD module. If the library you are using does support AMD, or has 2 versions (one that supports AMD, and one that is a global variable) you should use the AMD version. You should use the AMD version for the same reasons you would use AMD in the first place and also because the library may include require.js (or Almond ) in its source and would be adding unnecessary file size to your project.

like image 38
hapticdata Avatar answered Sep 20 '22 21:09

hapticdata