Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Javascript

Walkthrough: Using the RequireJS Optimizer

5.00/5 (6 votes)
24 Feb 2013CPOL5 min read 27.5K  
The goal of this post is to provide a brief overview of what it takes to compile your web site using RequireJS optimizer.

The goal of this post is to provide a brief overview of what it takes to compile your web site using RequireJS optimizer. This post assumes that you’re familiar with using RequireJS to load your AMD-based web site. If not, check out the RequireJS web site.

Note: Along with standard .NET 4.5 components, this walkthrough will require use of NodeJS. This is a lightweight install and can be downloaded from http://nodejs.org.

Let’s Get Started

We’ll create a very simple application that contains only three modules:

  • main.js
  • data.js
  • alerter.js

Step 1: Create the Visual Studio Project

Open up Visual Studio 2012 and create an empty ASP.NET web site named RjsDemo:

clip_image002

Step 2: Install RequireJS

Once the solution and project has been created, install the RequireJS NuGet package by typing Install-Package RequireJS into the Package Manager Console. Alternatively, you can right-click on the project in the Solution Explorer and choose Manage NuGet Packages…

Step 3: Start Coding!

Add some files and folders to your project so that your Solution Explorer looks like this:

clip_image004

Add code to each of the files as shown below:

js/alerter.js
JavaScript
define(function (require) {
    var logs = [];
    function log(message) {
        logs.push(message);
    };
    return {
        writeLog: log,
        logs: logs
    };
});
js/data.js
JavaScript
define(function (require) {
    var alerter = require("./alerter");

    function get(url, data) {
        alerter.writeLog("data.get for url: " + url);
    }

    return {
        get: get
    };
});
js/main.js
JavaScript
//require js config require.config({
    baseUrl: "/",
    urlArgs: "cachebust=" + (new Date()).getTime()
});


//main module define(function (require) {

    //use the simplified syntax to add dependencies var data = require("js/data");
    var alerter = require("js/alerter");

    //call a function on each module    alerter.writeLog("Starting app");
    data.get("getmovies", { id: 25 });

    //display logs    alert(alerter.logs.join('\n'));
});
index.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head>
<title>RequireJS Optimization Demo</title>
<script src="Scripts/require.js" data-main="js/main"></script> </head> <body> </body> </html>

Step 4: Run the Application

Start the project to launch the application. If all goes well, you should see the JavaScript alert box below:

clip_image002[4]

Optimizing the Application

Now we have an AMD-based application that loads a few modules, executes a couple of functions, and displays a JavaScript alert box. Let’s see how easy it is to compile the modules down into a single file.

Step 1: Modify index.html

First, let’s modify the index.html file to use the new compiled file to run our application:

Replace the line that says:

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

With this one:

XML
<script src="_build/main-built.js"></script>

Save the file, and launch the application. You should get an empty screen and should not get any JavaScript alert box. This is because the main-built.js file does not exist yet.

Step 2: Add the Build Files

Add a top-level folder into your project and name it _build

Add the following files into the _build folder:

_build/build.bat
node ..\scripts\r.js -o build.json

Tip: When adding a Windows batch using Visual Studio, you’ll need to ensure that the file is encoded properly. You can set the encoding directly in Visual Studio by choosing File>SaveAs from the menu. Choose the Save dropdown in the resulting dialog and then choose Save with encoding. In the Advanced Save Options dialog, choose US-ASCII as shown below:

clip_image002[6]

_build/build.json
JavaScript
{
  "baseUrl": "../", "name": "js/main", "include": [
"Scripts/require"
    ], "exclude": [], "optimize": "uglify2", "out": "main-built.js", "insertRequire": [
"js/main"
  ]
}

Your solution explorer should now look like this:

clip_image002[8]

About the r.js optimizer

RequireJS comes with its own optimizer, called r.js. This optimizer is very powerful and has a lot of options, but we’ll stick to a simple set of options for this walkthrough. R.js will start at a specified module for the application, and will walk the entire dependency tree, including each module that it finds. RequireJS finds it dependencies by parsing the modules, looking for certain keywords. For more information visit the RequireJS optimization page.

Execute the r.js optimizer using Node

Open the command-line and navigate to the _build folder you just created.

Hopefully you’ve already installed NodeJS. If not, now is the time to do so. After installed Node, you may need to restart the command-prompt to ensure that NodeJs has been added to the system PATH variable.

Type build.bat and press Enter. You should see output similar to the following:

clip_image004[4]

If this completes successfully, it should create a new JavaScript file names main-built.js in the _build folder.

Launch the application again, and this time you should see the same alert box that you saw the first time.

Congratulation, your application has been optimized!

Inspecting the Network Requests

You can use your browser’s developer tools to inspect the network requests and see the difference between the optimized and un-optimized versions.

Here is a screenshot of the application running in Chrome without optimization:

clip_image006

Now, here is a screenshot after optimization:

clip_image008

As you can see, the network request count dropped from five requests to two requests.

You may notice that, in the optimized version, require.js doesn’t appear to be loaded at all. This is because the build.json file explicitly includes scripts/require as a dependency, which causes it to be included as part of the main-built.js file.

If desired, you could set include: [] in the build.json file, and then you’d need add a separate script tag in index.html to load require.js.

Notes about the r.js build configuration file: build.json

In this example, we are specifying a build configuration that r.js should use. It is possible to supply build options on the command-line, but I have found it much simpler to define and use a build configuration file, much like build.json.

Here’s a brief explanation of the build.json parameters:

  • baseUrl – this parameter sets the base path for the r.js compiler to use. It is relative to the current path.
  • name – specifies the module that should server as the root of the application. This dependency tree of modules to include will be figured out starting from this module.
  • include – a list of modules that should be included in addition to the modules found by processing the name module
  • optimize - specifies the type of optimization, or minification, to use, such as uglify2 or none
  • out – specifies the output file relative to the current location. This does not use baseUrl
  • insertRequire – when present, automatically inserts a require() statement for the specified module at the end of the built output file.

Conclusion

Hopefully this helps to see how the r.js optimizer can be used to compile and optimize an AMD based web site. There are many more options, including using almond.js as a replacement for requireJS (doesn’t work for all scenarios where full requires functionality is required.)

Resources

Tips

  • Want to compile the scripts together, but not minimize them? Specify optimize:none in the build.json file and run the optimizer. This will create the same main-built.js file, but it will be viewable source. This can help to understand how the file and dependencies are put together.
  • If you’re running into issues with your browser caching the JavaScript modules, you can add a cache-busting parameter to the default URL arguments that are used to retrieve and load a module.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)