Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Requirejs why and when to use shim config

I read the requirejs document from here API

requirejs.config({     shim: {         'backbone': {             //These script dependencies should be loaded before loading             //backbone.js             deps: ['underscore', 'jquery'],             //Once loaded, use the global 'Backbone' as the             //module value.             exports: 'Backbone'         },         'underscore': {             exports: '_'         },         'foo': {             deps: ['bar'],             exports: 'Foo',             init: function (bar) {                 //Using a function allows you to call noConflict for                 //libraries that support it, and do other cleanup.                 //However, plugins for those libraries may still want                 //a global. "this" for the function will be the global                 //object. The dependencies will be passed in as                 //function arguments. If this function returns a value,                 //then that value is used as the module export value                 //instead of the object found via the 'exports' string.                 return this.Foo.noConflict();             }         }     } }); 

but i am not getting shim part of it. why should i use shim and how should i configure, can i get some more clarification

please can any one explain with example why and when should we use shim. thanks.

like image 822
Anil Gupta Avatar asked Mar 18 '13 06:03

Anil Gupta


People also ask

What is shim in magento2?

Shim gives a guarantee to load the dependent files first always. If the dependent file will be not found, your js file will be not loaded. In the above syntax, if the jquery file is not loaded, the slick. js file will be never called on the page.

What is shim configuration?

Advertisements. jQuery uses shim configuration to define the dependencies for jQuery plugins and set a module value by declaring dependencies.

What is RequireJS shim?

As per RequireJS API documentation, shim lets you. Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value.

Is RequireJS still relevant?

RequireJS has been a hugely influential and important tool in the JavaScript world. It's still used in many solid, well-written projects today.


2 Answers

A primary use of shim is with libraries that don't support AMD, but you need to manage their dependencies. For example, in the Backbone and Underscore example above: you know that Backbone requires Underscore, so suppose you wrote your code like this:

require(['underscore', 'backbone'] , function( Underscore, Backbone ) {      // do something with Backbone  } 

RequireJS will kick off asynchronous requests for both Underscore and Backbone, but you don't know which one will come back first so it's possible that Backbone would try to do something with Underscore before it's loaded.

NOTE: this underscore/backbone example was written before both those libraries supported AMD. But the principle holds true for any libraries today that don't support AMD.

The "init" hook lets you do other advanced things, e.g. if a library would normally export two different things into the global namespace but you want to redefine them under a single namespace. Or, maybe you want to do some monkey patching on a methods in the library that you're loading.

More background:

  • Upgrading to RequireJS 2.0 gives some history on how the order plugin tried to solve this in the past.
  • See the "Loading Non-Modules" section of This article by Aaron Hardy for another good description.
like image 164
explunit Avatar answered Sep 29 '22 08:09

explunit


As per RequireJS API documentation, shim lets you

Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value.

- Configuring dependencies

Lets say you have 2 javascript modules(moduleA and moduleB) and one of them(moduleA) depends on the other(moduleB). Both of these are necessary for your own module so you specify the dependencies in require() or define()

require(['moduleA','moduleB'],function(A,B ) {     ... } 

But since require itself follow AMD, you have no idea which one would be fetched early. This is where shim comes to rescue.

require.config({     shim:{        moduleA:{          deps:['moduleB']         }      }  }) 

This would make sure moduleB is always fetched before moduleA is loaded.

- Configuring exports

Shim export tells RequireJS what member on the global object (the window, assuming you're in a browser, of course) is the actual module value. Lets say moduleA adds itself to the window as 'modA'(just like jQuery and underscore does as $ and _ respectively), then we make our exports value 'modA'.

require.config({     shim:{        moduleA:{          exports:'modA'         }      } 

It will give RequireJS a local reference to this module. The global modA will still exist on the page too.

-Custom initialization for older "browser global" scripts

This is probably the most important feature of shim config which allow us to add 'browser global', 'non-AMD' scripts(that do not follow modular pattern either) as dependencies in our own module.

Lets say moduleB is plain old javascript with just two functions funcA() and funcB().

function funcA(){     console.log("this is function A") } function funcB(){     console.log("this is function B") } 

Though both of these functions are available in window scope, RequireJS recommends us to use them through their global identifier/handle to avoid confusions. So configuring the shim as

shim: {     moduleB: {         deps: ["jquery"],         exports: "funcB",         init: function () {             return {                 funcA: funcA,                 funcB: funcB             };         }     } } 

The return value from init function is used as the module export value instead of the object found via the 'exports' string. This will allow us to use funcB in our own module as

require(["moduleA","moduleB"], function(A, B){     B.funcB() }) 

Hope this helped.

like image 35
nalinc Avatar answered Sep 29 '22 08:09

nalinc