Why do I need to add a "shim" for AngularJS when using Require.js?
requirejs
Solution
The rule is pretty simple: if a library/script/package/plugin is AMD-aware, then you don't need a shim. (Actually, you must not use a shim for it.) If it is not AMD-aware, then you need a shim.
A library/etc is AMD-aware if it detects that an AMD loader is present and calls `define` to make itself known to the loader.
jQuery from about 1.8 onwards has not needed a shim because it calls `define`. Angular, on the other hand, does not call `define`.
To know whether a specific piece of code needs a shim, you can read its documentation or if the documentation is not clear on this, then you can check the source code for a call to `define`. For instance jQuery 1.11.0 has this code:
// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
});
}
How it looks like will vary from one case to the other but the basic think you want to look for is the check that `define` exists, is a function, has the `amd` property set and the call to `define`.
(Note that jQuery is a special case where they decided to hard code the name of the module in the `define` call (first parameter: `jquery`). Generally the name of the module won't be present in the `define` call but will be left for RequireJS to infer on the basis of the file name.)
Problem
I have seen several examples that use this: main.js ``` /*global require*/ 'use strict'; require.config({ paths: { angular: './angular', app: './Content/app', ngAnimate: './Scripts/angular-animate', uiRouter: './Scripts/angular-ui-router' }, shim: { angular: { exports: 'angular' } } }); require(['angular', 'app'], function (angular) { angular.bootstrap(document, ['app']); }); ``` Can someone explain to me why the shim is needed? My application uses other modules such as angular-ui router, jQuery etc. Do I need to do something similar and add a shim for these?