In the following post I will compare immediately-invoked function expressions (IIFE) to Universal Module Definition (UMD) bundles.
A very popular example of this is jQuery plugins.
In the following example I will show how to encapsulate a simple CarService in an IIFE:
Below is the same CareService wrapped in an IIFE.
In addition to defining the CareService, the IIFE makes the service available via global scope by setting exports.CarService = CarService.
At runtime exports.CarService refers to global scope via this.carModule_IIFE.
We can now load the IIFE using a standard script tag like so:
After the script is loaded, carModule_IIFE.CarService is defined in global scope, and can be used to create instances of the services:
Please note that the _IIFE suffix is just I name I chose for illustration purposes.
UMDs overlap with IIFEs. The main difference is that UMDs are much more flexible when it comes to supported module loading formats.
Next I will show how an UMD version of the original CareService can be used with different module patterns.
At the top of the UMD you see several conditionals. These conditionals decide which module strategy to use based on the environment the code executes in.
Here are the different supported strategies:
Script Tag/Global Scope
The base case is to use an UMD the same way we used the IIFE.
The approach here is the same as before.
The second supported pattern in UMD is commonJS. This is a pattern commonly seen in nodeJS.
In nodeJS the UMD bundle can be loaded using a require statement.
The next supported pattern I will show is Asynchronous Module Definition (AMD).
I will continue my CarService sample by showing how to do AMD based loading of the service. For the purposes of this sample I will be using the requireJS library to implement AMD.
Please note, for all samples, the _UMD suffix is just I name I chose for illustration purposes.
As you can tell there is some overlap between IIFE and UMD, but UMD is much more flexible with support for many different module formats.