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:
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:
Add code to each of the files as shown below:
js/alerter.js
define(function (require) {
var logs = [];
function log(message) {
logs.push(message);
};
return {
writeLog: log,
logs: logs
};
});
js/data.js
define(function (require) {
var alerter = require("./alerter");
function get(url, data) {
alerter.writeLog("data.get for url: " + url);
}
return {
get: get
};
});
js/main.js
baseUrl: "/",
urlArgs: "cachebust=" + (new Date()).getTime()
});
var alerter = require("js/alerter");
data.get("getmovies", { id: 25 });
});
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:
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:
<script src="Scripts/require.js" data-main="js/main"></script>
With this one:
<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:
_build/build.json
{
"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:
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:
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:
Now, here is a screenshot after optimization:
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.