Introduction to RequireJS for Modular Programming

In this tutorial we are going to look at Requirejs an incredibly powerful AMD(Asynchronous Module Definition) compatible script loader.To achieve this modular programming came into picture.

Modular Programming

Modular programming is used to break large applications into smaller blocks of manageable code. Module based coding eases the effort for maintenance and increases reusability of code. However, managing dependencies between modules is a major concern developers face throughout the application development process. Requirejs is one of the most popular frameworks around for managing dependencies between modules.In this tutorial we will see how requirejs helps us.

Why we need Javascript loaders 

Due to evolution of Single page applications web applications requires large number of script files.Generally they all are loaded one by one using <script> tag.Each file can potentially dependent on other script file.A common example for this is jquery plugins in web applications.For all jquery plugins jquery core library file must be loaded.Let look this using a simple real time example.Let's assume we have 3 javascript files.

purchase.js

function purchaseProduct(){
  //gets credits to purchase product
  var credits = getCredits();
  if(credits > 0){
    //checks the product available or not
    reserveProduct();
    return true;
  }
  return false;
}

product.js

function reserveProduct(){
  alert("Function : reserveProduct()");
  return true;
}

credits.js

function getCredits(){
  alert("Function : getCredits");
  var credits = "100";
  return credits;
}
In above example we are trying to purchase a product.First it checks whether credits available or not.If credits are available it reserves the product.Here purchase.js file depends upon credits.js and product.js files.Now in another script file main.js i am initializing code purchase.js as shown below.
var result=purchaseProduct();
So,credits.js and product.js files need to loaded before purchase.js file.We have to place those script files in order.What would happen if we place files in wrong order as shown below.
<script src="products.js"></script>
<script src="purchase.js"></script>
<script src="main.js"></script>
<script src="credits.js"></script>
Here the initialization of script(main.js) is done before credits.js loaded this will result an error like below.



In current example we just have 3 script files for larger applications the number of script files are also more and things can easily get out of control.That's where requirejs come into picture.

Introduction to Requirejs

1.Requirejs is a popular java script module loader which is supported by all latest version browsers.
2.In requirejs we separate code in modules which can handle single responsibility.
3.And dependencies need to be configured before loading script files.
4.Lets start the implementation of an small application by downloading requirejs.
Lets assume our project directory will look like below.


The file main.js file is used for initializing scripts.Lets see how scripts are included in html page using requirejs.

<script data-main="scripts/main" src="~/Scripts/require.js"></script>

This is the only code required to include files using Requirejs.You might be wondering what happened to the other files and how they are included. The data-main attribute defines the initialization point of the application. In this case, it is main.js. Requirejs uses main.js to look for other scripts and dependencies. In this scenario all the files are located in same folder(Scripts folder). you can move the files to any folder you prefer.

Creating Application with Requirejs

 In Requirejs all script code wrapped into require() and define() functions.Lets look at main.js file.

require(["purchase"], function (purchase) {
    purchase.purchaseProduct();
});

1.In above code the first parameter of the function require() specifies dependencies.We already know the initialization dependent on purchase.js file.
Note: Here see the .js extension is omitted. Requirejs only considers .js file only.
2.Second parameter is an anonymous function which takes an object as parameter which is used to call functions inside dependent script files see in above code.
Note: We can load multiple script dependencies using below syntax.

require(["a","b","c"],function(a,b,c){
});

Now we are going to convert the plain script files into Requirejs like below.

purchase.js

 define(["credits","products"], function(credits,products) {
  console.log("Function : purchaseProduct");
  return {
    purchaseProduct: function() {
      var credit = credits.getCredits();
      if(credit > 0){
        products.reserveProduct();
        return true;
      }
      return false;
    }
  }
});

Here,first we declare that purchase functionality depends on credits and products. Inside the return statement, we can define the functions of each module. Here, we have called the getCredits() and reserveProduct() functions on the objects passed. product.js and credits.js are similar, and are shown below.

products.js

define(function(products) {
  return {
    reserveProduct: function() {
      console.log("Function : reserveProduct");
      return true;
    }
  }
});

credits.js

define(function() {
  console.log("Function : getCredits");
  return {
    getCredits: function() {
      var credits = "100";
      return credits;
    }
  }
});

Both files products.js and credits.js are configured as independent modules(defined with define() function).They are dependent on anything.Here the important thing to notice is the difference between require() and define() functions.

Difference between require() and define()

In Requirejs we can use both require() and define() functions to load dependencies.Understanding the difference between this both is essential in managing dependencies.Lets see the differences,

require() 

require function is used to used to run the immediate functionalities.For example we used require in main.js in above example.

define()

define function is used to define modules that are used for multiple locations.In above example we defined products.js and credits.js with define function.The files which are defined by define() function are reusable modules.

Note: In plain java script example, an error was generated due to the incorrect order of file loading. Now, delete the credits.js file in the Requirejs example and see how it works. The following image shows error in browser inspection tool.


The difference here is that no code has been executed in the Requirejs example.We can confirm it since nothing is printed on the console(we wrote console.log in almost every file). In the plain JavaScript example we had some output printed on the console before generating the error. Requirejs waits until all the dependent modules are loaded before executing the functionality. If any modules are missing, it doesn’t execute any code. This helps us maintain the consistency of our data.

Managing order of dependent files

Requirejs uses Asynchronous module loader for loading files.Each dependent module will start loading through asynchronous requests.Even though files ordered is considered due to synchronous nature we can not guarantee that the first file loaded before second file.For that Requirejs allows us to define the sequence of the files using shim config to load in correct order.
Lets how to use shim config,

requirejs.config({
  shim: {
    'source1': ['dependency1','dependency2'],
    'source2': ['source1']
  }
});

Requirejs allows us to provide configuration options using the config() function. It accepts a parameter called shim which we can use to define the mandatory sequences of dependencies see above code.You can find advanced configuration guide in API Documentation of Requirejs.
Using shim config it is mandatory to load dependent before calling files.

Conclusion

I hope this article may helped you to understand the basics of Requirejs.This tutorial is not enough to manage dependencies.You can find advanced tutorial on requirejs from official site documentation.
Introduction to RequireJS for Modular Programming Introduction to RequireJS for Modular Programming Reviewed by raviteja swayampu on 05:44:00 Rating: 5

No comments: