$script.js vs RequireJS: Dependency Management Comparisons

As JavaScript moves further and further away from the playground programming language that it used to be, and is used more and more as the core for large-scale applications, managing the code starts to become extremely difficult. Splitting the code into multiple files helps with that, though it also adds more complexity in a different way. One way to fight this new complexity is with dependency management libraries, but which one is right for you?

Script Loading vs Dependency Management

The two libraries mentioned in the title – $script.js and RequireJS – are not technically classified in the same way because though they do similar things, they have different emphasis. $script.js is a script loader with dependency management, and while RequireJS is the same way, it’s dependency management is much more powerful and more closely resembles what you would use for importing classes in compiled languages such as Java. You’ll see what I mean soon.

$script.js

This handy library was created by Dustin Diaz and Jacob Thornton and is hosted on Github. That’s where you’ll find the documentation on how to use it, but I’ll still show it off a bit here to give you an idea of how it works. I’ve actually already written an article about this library – which happens to be the first post ever on this blog – but its focus was quite different.

First, we’ll talk about the most basic usage: loading a script.

1
$script('jquery.js');

This loads jquery.js asynchronously onto the page. This is no more useful than just using a normal script tag though. It’s slightly shorter, but since it is loaded asynchronously, the code right after this line will run before jquery.js is loaded. So, we also give it a callback function that runs after jquery.js is loaded.

1
2
3
$script('jquery.js', function() {
// do stuff with jQuery.
});

Now, once jquery.js is loaded and executed, we’ll be sure that we can access the objects and functions that it defines. There is so much more you can do with $script.js – including named dependencies – but this gives you the gist of how to use it. With this, we’ve successfully defined a dependency and assured the dependency would be loaded and executed before we tried to use it. Using something like this allows us to only need to use 2 script tags in our HTML (one to load $script.js and one to load the main application). The rest of the scripts that we depend on can be managed with $script.js.

RequireJS

RequireJS is a much larger project, with a Github project and a site of its own. You’ll find the documentation for RequireJS at that second link, but if you want to read some history and a more thorough introduction to RequireJS you can read this article on Adobe Developer Connection.

RequireJS can be use almost exactly like $script.js to load plain JavaScript files, but it’s so much more powerful than that. You can define modules, and then load those module dependencies in without exposing them globally, so that every bit of your code can be safe from 3rd party scripts. Take a look.

First we’ll just define a module that can pulled in as a dependency.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// This is just an object literal
define({
name: "Joe Zim",
gender: "male"
});

// Here's a constructor so you can create
// new objects, rather than just the one
// literal object
define(function() {
var Person = function( name, gender ) {
this.name = name;
this.gender = gender;
};

return Person;
} );

You can see two different types of modules there. The first one is just defined as an object literal, which will be what is returned to the dependent script, as you’ll see later. The second example has a function, which will be run immediately when the module is loaded as a dependency and the value that is returned from that function will be the value that is given to the dependent script.

Now we’ll create a module that is dependent on the module we just defined. We’ll assume that the module above is saved as person.js. Here’s how we define another module that is dependent on the module we just made, plus another module that was created behind the scenes.

1
2
3
4
5
6
7
8
9
define( [
'person', 'list'
], function( Person, List ) {
var personList = new List(
new Person('Joe Zim', 'male');
);

return personList;
} );

We define the module exactly as we did before, except this time we send in an array as the first parameter. The array lists strings of file names (sans the “.js”) of modules to fetch. Then, when those modules are fully loaded, they are sent in as parameters to the function for the new module you are defining. As stated above, this localizes the modules so they are not accessible globally.

Now we’ll write a bit of code that is dependent on the latest module and the person module, but isn’t creating a new module. We’ll assume that the latest created module is saved as default-person-list.js.

1
2
3
4
5
6
7
8
9
10
require( [
'default-person-list', 'person'
], function( list, Person ) {
var chuck = new Person( 'Chuck Norris', 'male' );
list.addItem( chuck );

list.forEach( function( item ) {
alert(item.name);
} );
} );

This is almost exactly the same as creating a module that is dependent on another module except for a couple important things:

  1. We no longer use the define function; instead we use require (finally we know where the name of the library comes from!).
  2. There’s no need to return anything from the function. Since this is not being defined as a module, it is just run as is and therefore has no need to return anything.

That’s the gist of RequireJS, but there’s one more thing that’s pretty important to note about RequireJS. It comes with a build tool that will look through all of the modules and other JavaScript files and concatenate and minify them so that even though you spent all that time create separate files, it won’t become a performance problem.

What’s Right For You?

If you are a very modular programmer and you enjoy the idea of keeping the modules localized, then taking the RequireJS route is probably a really good idea for you. If your application is relatively simple or you just don’t like the idea of converting everything into individual module files, then something like $script.js would probably be a great fit. Ultimately it’s up to you, as they are both great tools. Anyway, that’s all for today; Happy coding and God Bless!

Author: Joe Zimmerman

Author: Joe Zimmerman Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.