Tuesday, July 9, 2013

Basics of RequireJS


I hear a lot of about RequireJS and today I decided to learn this. So for start let's read what is RequireJS.

What is it?

We can read from documentation that RequireJS is:

... a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.



Because I'm not so good with theory let's practice. We gonna create simple calculator application which allows to do simple things like:

  • addition,
  • sustraction,
  • multiplication,
  • division
  • and calculating the square of numbers.

Let's begin

First we need include requirejs file into our html file for example using url from documentation:
src="http://requirejs.org/docs/release/2.1.7/comments/require.js"

Now let's create our first method of calculator add. How we can do that. Normally we create new file for example: "scripts.js" where we creates functions needed to our application. Then in this file we can create this simple function:

function add (x, y) {
 return x + y;
}

It's look ok right? No! because in this case add scope is global what mean that goes into window scope. We can easily lose control on our variables. Let's imagine that we use some external library where someone too define method add. What it mean? In this case one of add function override another and application will not work.

To solve this problem we gonna use  Asynchronous Module Definition (AMDmechanism.

Step 1. Define

First we create new file. Let's call it add.js and there put addition function which return result of add:


define(function(){
 return function(x, y){
  return x + y;
 };
});

Step 2. Using


Now if we want use this module we need add require to file where we need this. Let's create next file (app.js) which we include into our html file and write that code:

require(['add'], function(Add){
 console.log(Add(1,1));
});
In first line as first parameter of require method we pass array of javascript file names. You must know that if we put add file into folder for example js then we need write 'js/add'  instead of add.
Second parameter is a function where as params we write variable names which we gonna next use as module. In this case I simply write Add.
In function body I just log into console result of add method from our first module.

What now?

Now in the same way we create modules and files for sustraction, multiplication and division. To use all of modules we will need modify our app.js file:

require(['add', 'substract', 'multiply', 'divide'],
  function(Add, Sub, Multi, Div){
 console.log(Add(1,1));
 console.log(Sub(3,1));
 console.log(Multi(2,3));
 console.log(Div(10,5));
});

Instead of including new file into our html document we can add data-main attribute to script tag where we include requireJS file. In this way we define our main application file.

Now little reorganize our structure of application. Let's put all modules into js folder and leave app.js file in main directory of our application. Now let's create calculator module which will be used to do calculations.

define(['js/add', 'js/substract', 'js/multiply', 'js/divide'],
   function (Add, Substract, Multiply, Divide) {

 return {
  add : function(a,b) {
   return Add(a,b);
  },

  sub : function (a,b) {
   return Substract(a,b);
  },

  multi : function (a,b){
   return Multiply(a,b);
  },

  divide : function (a,b) {
   return Divide(a,b);
  },

  square : function (a) {
   return Multiply(a,a);
  }
 };
});

Like you can notice I also add here square method which use multiply module to return result. We also using here dependency in define. So our simple modules are called by calculator which is called by our main application file:

require(['js/calculator'], function (Calc) {
 console.log(Calc.add(1,1));
 console.log(Calc.sub(3,1));
 console.log(Calc.multi(2,3));
 console.log(Calc.divide(10,5));
 console.log(Calc.square(5));
});

Full code you can find on GitHub:
https://github.com/lukasz-zak/requireJS-training

Summary

Like you can see it's easy and very useful. It's allows us to organize our code into reusable modules. There is also easier for developers who work together on the same project to work on different files which are modules. Normally they would work on one file where then this can cause some problems with versioning.

This is my first big post so be nice for me and don't shy to correct me or help to improve this post. If something isn't clear I will try help.

No comments :

Post a Comment