RequireJS Optimizer

The next chapter after Get into RequireJS

This time I will explain how you can optimize your project code when you are using RequireJS.

RequireJS has an optimization tool that does the following

  • Combines related scripts together into build layers and minifies them.
  • Optimizes CSS by inlining CSS files referenced by @import and removing comments.

With the optimizer, you can optimize just a single file, or you can optimize all the CSS and JS files in your project by using a build profile.

Requirements

There are different ways and different tools to do this, but my preference will go to run using Node.

So, if you don’t have node installed on your machine, go to node page and install it. Then, you need to download the optimizer from here.

Place the optimizer in the up folder of your project. Now, you need to create a build file with the all necessary configuration.

For my demo in the Get into RequireJs it looks like this:


({
  appDir: "../",
  baseUrl: "scripts",
  dir: "../../requirejs-demo-build",
  paths: {
    jquery: 'lib/jquery'
  },
  modules: [
    {
      name: "app/blog"
    },
    {
      name: "app/dataservice"
    },
    {
      name: "app/presenter"
    }
  ]
})

Note: Your output folder should always be different from the development folder!

Put your config file in the scripts folder (or you could put it anywhere, but be aware that all the paths are relative to the config file!)

And finally, to run the build, run this command from inside the scripts directory:


node ../../r.js -o app.build.js

The output should be something like this:


Optimizing (standard.keepLines) CSS file: c:/wamp/www/requirejs-demo-build/css/style.css

Tracing dependencies for: app/blog

Tracing dependencies for: app/dataservice

Tracing dependencies for: app/presenter
Uglifying file: c:/wamp/www/requirejs-demo-build/scripts/app/blog.js
Uglifying file: c:/wamp/www/requirejs-demo-build/scripts/app/dataservice.js
Uglifying file: c:/wamp/www/requirejs-demo-build/scripts/app/presenter.js
Uglifying file: c:/wamp/www/requirejs-demo-build/scripts/app.build.js
Uglifying file: c:/wamp/www/requirejs-demo-build/scripts/app.js
Uglifying file: c:/wamp/www/requirejs-demo-build/scripts/lib/jquery.js
Uglifying file: c:/wamp/www/requirejs-demo-build/scripts/lib/require.js

css/style.css
----------------
css/style.css

scripts/app/blog.js
----------------
scripts/lib/jquery.js
scripts/app/dataservice.js
scripts/app/presenter.js
scripts/app/blog.js

scripts/app/dataservice.js
----------------
scripts/lib/jquery.js
scripts/app/dataservice.js

scripts/app/presenter.js
----------------
scripts/lib/jquery.js
scripts/app/presenter.js

No if you open the output folder, you will see that your javascript code is now minified!

Advertisements

Get into RequireJS

Intro

Hi all, welcome to Get Into RequireJS! If you have good skills on javascript and already knows about the Revealing Module Pattern, get ready because, I will go cut to the chase!

What is RequireJS?

RequireJS is a module loader. Its functionality is to load modules and take care of dependencies for you. When you define a module, you will identify its dependencies and RequireJS will load those dependencies in runtime and just when they are needed!

How to add RequireJS to the project?

RequireJs assumes that you have a specifc directory structure in your project. Of course you can override this settings, but for the demonstration I will follow the default structure, which is the following:

project-directory/

  • project.html
  • scripts/

Under the scripts folder, you will have all the javascript for your project. I always suggest to have the third party libraries separated from your files, so, in my demo I have the following structure:

project-directory/

  • blog.html
  • scripts/
    • app/
    • lib/
    • main.js

Where my code goes to app folder and third party goes to the lib folder.

In the html page you will just include the RequireJS:


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

The data-main attribute, indicates to RequireJS, that once it is loaded, it will have to load the scripts/main.js file. There are other ways to do this, but this one, without any configuration, is definitely the simplest one. Note that I did not refer main.js but only main, this is because RequireJS expects to load only javascript files, so you can omit the extension when you refer your modules.

On the main.js, normally I have some RequireJS configuration and the first call to my application API:


// requirejs configuration

// Define baseUrl (the base folder for the js files)

// Define path to jQuery

requirejs.config({

  baseUrl: 'scripts',

  paths: {

    jquery: 'lib/jquery'

  }

});

// Start the main app logic.

requirejs(['app/blog'],

  function (blog) {

    blog.start();

  });

In the code to start the application, I am saying to RequireJS that I need the module blog and then I can call my function that starts the application. We will just see how that works.

How to define a module?

The structure of a RequireJs module, follows the Module Pattern

In my demo I have the following module (file app/blog.js):


define(['app/dataservice', 'app/presenter'], function(dataservice, presenter){

  var start = function(){

    dataservice.getPosts(presenter.renderPosts);

  };

  return {

    start: start

  }

})

The code indicates that the module blog, depends on dataservice and presenter modules. On the start function, I am calling getPosts on dataservice module and I am passing the renderPosts on the presenter module as callback (not the best way, but for demo purpose is fine).

Picking one of the dependencies modules, for instance the dataservice, it is very similar as it also follows the same structure:


define(['jquery'],function($){

  var getPosts = function(callback){

  $.get('data/posts.json',callback)

  };

  return {

    getPosts: getPosts

  }

})

Final notes

There are a lot of configuration that you can do, different ways to load modules but, this was a cut to the chase, just to show how easy is to use RequireJS. If you thought it was interesting and want to start using it, I suggest to take a look at the documentation first.

You can download my complete demo in Github.

preview

jQuery Custom Events

jQuery custom events are a great feature to deal with complex situations or non trivial situations.
You can create a custom event that reacts to a particular situation that is not defined with jQuery.

You can attach a custom event just like this:


$('#someElement').on('myCustomEvent', handlerForCustomEvent)

and trigger it like this:


$('#someElement').trigger('myCustomEvent');

Note: You can also attach custom events to non DOM elements, like an object of any class for exemple.

You can see a demo of these feature in this jsFiddle.