RequireJS
A JavaScript Module Loader
Greg Franko
1/30/2014
Use arrow keys to navigate
About The Speaker
Greg Franko
JavaScript Engineer at AddThis
Open Source Developer
Author
Speaker
Why Do People Use RequireJS?
Asynchronous and Dynamic Loading
Decoupled Code into Modules
What Projects/Companies Use RequireJS?
Used in Development, Removed In Production
RequireJS in Development, AlmondJS In Production
Used In Both Development and Production
Used In Both Development and Production
RequireJS in Development, AMDCleanJS In Production
Are You Using RequireJS?
It's Okay If You Aren't
RequireJS Basics
Let's Learn
Most Projects Start Like This:
JavaScript files are included as HTML script tags
<body>
<script src='jquery.js'></script>
<script src='jquery-ui.js'></script>
<script src='lodash.js'></script>
<script src='backbone.js'></script>
<script src='init.js'></script>
<script src='app.js'></script>
</body>
This Is Fine...
-
If you don't have many dependencies
-
If you don't care about page load performance
-
If you don't like decoupled code
This Is Better:
Only Require.js is included as an HTML script tag
<body>
<script src='require.js' data-main='init'></script>
</body>
data-main
- Tells Require.js to load init.js
first
Huh?
init.js
is getting loaded, but none of my other JavaScript files are
RequireJS is the worst
Everything Will Be Okay!
You haven't told RequireJS that init.js
depends on jQuery, jQueryUI, Lodash, and Backbone
How Do I Tell RequireJS About My File Dependencies?
-
By writing init.js
in a format that Requirejs understands
What Format?
-
Asynchronous Module Definition
init.js AMD Example
// init.js
// Depends on jQuery, jQueryUI, Lodash, and Backbone
define(['jquery', 'jqueryui', 'lodash', 'backbone'], function($, null, _, Backbone) {
/* This function gets called after
jquery.js, jqueryui.js, lodash.js,
and backbone.js are loaded
*/
});
Awesome, It Works!
RequireJS Is The Best
Please Tell Me More About AMD
AMD
-
Module Format Used By RequireJS
-
Exposes Two Global Methods:
If define
Is Still Confusing...
Is That It?
-
Nope, There Are Many Ways To Define an AMD Module
-
-
Loads One Or More AMD Modules
-
// Loads the example.js module from our first define() example
require(['./example.js'], function(exampleText) {
// Prints: 'example.js return value: No dependencies, returns a string'
console.log('example.js return value: ', exampleText);
})
-
That's All There Is To The require()
Method
Should I Use define
or require
?
-
You Should Use Both
-
Use define
to wrap logic that you would like to re-use somewhere else in your application
-
Use require
when you just want a dependency to be loaded onto the page.
Now What?
-
Now That You Understand How To Create And Load AMD Modules...
-
Let Me Answer Your Question With A Question
-
Have You Ever Used JavaScript Code That You Didn't Write?
Third Party Libraries
-
Cannot Assume AMD Is Being Used
-
Can Still Provide Conditional Support
How Would A Third Party Library Provide AMD Support?
jQuery
Provides AMD Support via a Named AMD module
Lodash
Provides AMD Support via an Anonymous AMD module
Backbone
Does Not Provide AMD Support yet
How Do You Use Scripts That Are Not AMD Compatible?
Useful for libraries that export a global variable
requirejs.config({
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
});
Is This Black Magic?
-
No, RequireJS just creates a define
wrapper for all shimmed libraries
-
define("backbone", ["underscore","jquery"], (function (global) {
return function () {
var ret, fn;
return ret || global.Backbone;
};
}(this)));
Also Useful for Declaring Dependencies
require.config({
shim: {
'jquery.ui.widget': ['jquery'],
'jquery.selectBoxIt': ['jquery.ui.widget']
}
});
Hold Up
-
Can You Explain The require.config()
Method?
-
RequireJS allows you to set application-level configuration options
-
The configuration options should be set before you define/require any modules
-
The beginning file path that is used for all of the file lookups
-
Allows you to map module IDs to alias names (easier to type
'jquery'
than '../../jquery
')
-
Allows you to make third-party libraries AMD compatible
Let's Review
-
Define()
allows you to create AMD modules
-
Require()
allows you to load one or more AMD modules onto the page
-
RequireJS configuration options provide flexibility and convenience
-
Last but not least...
-
Node.js Command-Line Build Tool
-
Concatenates Your AMD Project Into One File
-
-
Can Be Used with Grunt or Gulp
Example Build Profile
{
baseUrl: "public/js/",
paths: {
"desktop": "app/config/Init"
},
optimize: "uglify",
mainConfigFile: "public/js/app/config/Init.js",
include: ["desktop"],
out: "public/js/app/config/Init.min.js"
}
Common Optimizer Questions
-
I thought RequireJS Didn't Require A Build Step?
It doesn't, the optimizer is optional.
-
Why Would I use the RequireJS Optimizer?
If you want to build your project into one file
-
Do I Still Need RequireJS After I Build?
If you need to load any additional network resources with RequireJS, then yes. Otherwise, you may use Almond.js or AMDClean.js.
-
A Minimal (~400 line) RequireJS Replacement After Optimized Builds
-
Does Not Allow Loading Network Resources
-
Does Not Transform Source Code
- Example Build With Almond.js
-
An AMD Build Tool That Converts AMD Code To Standard JavaScript
-
Allows You To Use AMD In Development Without Having To Include an AMD Library In Production
-
Does Not Allow Loading Network Resources
-
Transforms Source Code
- Example Build With AMDClean.js
For A Complete Example, Check Out:
Additional Topics That May Interest You
Browserify vs RequireJS
Using CommonJS syntax with RequireJS
ES6 Modules and The Future