require.js
a keynote information loader
about
a javascript module loader
Wednesday, March 27, 13
what is requires
• a javascript module loader
Wednesday, March 27, 13
where to get it?
• http://requirejs.org
Wednesday, March 27, 13
who has it?
wget http://requirejs.org/docs/release/2.1.5/minified/require.js
-O ./public/js/require.min.js
wget http://requirejs.org/docs/release/2.1.5/comments/require.js
-O ./public/js/require.js
Wednesday, March 27, 13
why do I need it?
• Web sites are turning into Web apps
Wednesday, March 27, 13
why do I need it?
• Web sites are turning into Web apps
• Code complexity grows as the site gets
bigger
Wednesday, March 27, 13
why do I need it?
• Web sites are turning into Web apps
• Code complexity grows as the site gets
bigger
• Assembly gets harder
Wednesday, March 27, 13
why do I need it?
• Web sites are turning into Web apps
• Code complexity grows as the site gets
bigger
• Assembly gets harder
• Developer wants discrete JS files/modules
Wednesday, March 27, 13
why do I need it?
• Web sites are turning into Web apps
• Code complexity grows as the site gets
bigger
• Assembly gets harder
• Developer wants discrete JS files/modules
• Deployment wants optimized code in just
one or a few HTTP calls
Wednesday, March 27, 13
how does it solve this?
• Some sort of #include/import/require
Wednesday, March 27, 13
how does it solve this?
• Some sort of #include/import/require
• ability to load nested dependencies
Wednesday, March 27, 13
how does it solve this?
• Some sort of #include/import/require
• ability to load nested dependencies
• ease of use for developer but then backed
by an optimization tool that helps
deployment
Wednesday, March 27, 13
how do I use require.js?
// index.html
<script data-main="scripts/main" src="scripts/require.js"></script>
// scripts/main.js
require(["loc/module"], function(module) {
//This function is called when scripts/loc/module.js is loaded.
//If module.js calls define(), then this function is not fired until
//util's dependencies have loaded, and the util argument will hold
//the module value for "helper/util".
});
Wednesday, March 27, 13
how do I use require.js?
// index.html
<script data-main="scripts/main" src="scripts/require.js"></script>
// scripts/main.js
require(["loc/module"], function(module) {
//This function is called when scripts/loc/module.js is loaded.
//If module.js calls define(), then this function is not fired until
//util's dependencies have loaded, and the util argument will hold
//the module value for "helper/util".
});
Wednesday, March 27, 13
how do I use require.js?
// index.html
<script data-main="scripts/main" src="scripts/require.js"></script>
// scripts/main.js
require(["loc/module"], function(module) {
//This function is called when scripts/loc/module.js is loaded.
//If module.js calls define(), then this function is not fired until
//util's dependencies have loaded, and the util argument will hold
//the module value for "helper/util".
});
Wednesday, March 27, 13
writing a module, today
(function ($) {
function Foo() {
// do stuff here!
}
new Foo();
}(jQuery));
Wednesday, March 27, 13
writing a module, today
var $ = require('jquery');
exports.myExample = function () {
// do stuff here!
};
Wednesday, March 27, 13
writing a module,
today++: AMD
define('mod',function(){
return function() {
this.boom = function ()
{
alert( 'Boom' );
};
}
} );
Wednesday, March 27, 13
What is AMD?
• Asynchronous Module Definition
Wednesday, March 27, 13
why is this good?
• Uses the CommonJS practice of string IDs for dependencies
• IDs can be mapped to different paths.
• Encapsulates the module definition.
• Clear path to defining the module value.
• Allows setting a function as a return value. Useful for constructor functions.
• Defines a way to include multiple modules in one file.
Wednesday, March 27, 13
why is this good?
• Easy to test, because modules are compartmentalized
• Dependency Injection
Wednesday, March 27, 13
amd still handles this
(function () {
this.myGlobal = function () {};
}());
Wednesday, March 27, 13
require still supports
normal javascript
require(["some/script.js"], function() {
//This function is called after some/script.js has loaded.
});
Wednesday, March 27, 13
It’s easy!
• http://requirejs.org/docs/why.html
Wednesday, March 27, 13
Optimization!
• We can compile all requirements into one
file
• We can minimize CSS and JavaScript using
Closure Compiler (or UglifyJS)
• We aren’t worried about CSS today
Wednesday, March 27, 13
Can run...
• In the browser
• In Node
• In Rhino
Wednesday, March 27, 13
Using Closure
Compiler
• Means uses Java
• Means using Rhino
• r.js
Wednesday, March 27, 13
testing
define( 'mod', ['Profile'], function ( Profile ) {
function mod() {
this.boom = function () {
return (new Profile()).mockTrueLol();
};
}
return mod;
} );
Wednesday, March 27, 13
JSTestDriver
# tests.jstd
load:
- r.js
- webapp/tests/app.build.test.js
# This let’s JSTestRunner serve up all the scripts for require
serve:
- webapp/scripts/*.js
# Could also just do - webapp/tests/*.js
test:
- webapp/tests/GangTest.js
- webapp/tests/LandTest.js
- webapp/tests/ProfileTest.js
- webapp/tests/TestJSTestDriver.js
Wednesday, March 27, 13
JSTestRunner
# tests.jstd
load:
- r.js
- webapp/tests/app.build.test.js
# This let’s JSTestRunner serve up all the scripts for require
serve:
- webapp/scripts/*.js
# Could also just do - webapp/tests/*.js
test:
- webapp/tests/GangTest.js
- webapp/tests/LandTest.js
- webapp/tests/ProfileTest.js
- webapp/tests/TestJSTestDriver.js
Wednesday, March 27, 13
JSTestRunner
# tests.jstd
load:
- r.js
- webapp/tests/app.build.test.js
# This let’s JSTestRunner serve up all the scripts for require
serve:
- webapp/scripts/*.js
# Could also just do - webapp/tests/*.js
test:
- webapp/tests/GangTest.js
- webapp/tests/LandTest.js
- webapp/tests/ProfileTest.js
- webapp/tests/TestJSTestDriver.js
Wednesday, March 27, 13
JSTestRunner
# tests.jstd
load:
- r.js
- webapp/tests/app.build.test.js
# This let’s JSTestRunner serve up all the scripts for require
serve:
- webapp/scripts/*.js
# Could also just do - webapp/tests/*.js
test:
- webapp/tests/GangTest.js
- webapp/tests/LandTest.js
- webapp/tests/ProfileTest.js
- webapp/tests/TestJSTestDriver.js
Wednesday, March 27, 13
(function (){
TestJSTestDriver
var Mod;
AsyncTestCase( "TestJSTestDriver", {
setUp: function ( queue ){
queue.call( function ( callbacks ){
require.undef( 'Profile' );
define( 'Profile', function (){
function Profile() {}
Profile.prototype.mockTrueLol = function() {
return true;
};
return Profile;
} );
require( [ 'mod' ], callbacks.add( function ( m ){
Mod = new m();
} ) );
} );
},
// tests here
} );
})();
Wednesday, March 27, 13
TestJSTestDriver
(function (){
var Mod;
AsyncTestCase( "TestJSTestDriver", {
setUp: function ( queue ){
queue.call( function ( callbacks ){
require.undef( 'Profile' );
define( 'Profile', function (){
function Profile() {}
Profile.prototype.mockTrueLol = function() {
return true;
};
return Profile;
} );
require( [ 'mod' ], callbacks.add( function ( m ){
Mod = new m();
} ) );
} );
},
// tests here
} );
})();
Wednesday, March 27, 13
(function (){
TestJSTestDriver
var Mod;
AsyncTestCase( "TestJSTestDriver", {
setUp: function ( queue ){
queue.call( function ( callbacks ){
require.undef( 'Profile' );
define( 'Profile', function (){
function Profile() {}
Profile.prototype.mockTrueLol = function() {
return true;
};
return Profile;
} );
require( [ 'mod' ], callbacks.add( function ( m ){
Mod = new m();
} ) );
} );
},
// tests here
} );
})();
Wednesday, March 27, 13
(function (){
TestJSTestDriver
var Mod;
AsyncTestCase( "TestJSTestDriver", {
setUp: function ( queue ){
queue.call( function ( callbacks ){
require.undef( 'Profile' );
define( 'Profile', function (){
function Profile() {}
Profile.prototype.mockTrueLol = function() {
return true;
};
return Profile;
} );
require( [ 'mod' ], callbacks.add( function ( m ){
Mod = new m();
} ) );
} );
},
// tests here
} );
})();
Wednesday, March 27, 13
(function (){
TestJSTestDriver
var Mod;
AsyncTestCase( "TestJSTestDriver", {
setUp: function ( queue ){
queue.call( function ( callbacks ){
require.undef( 'Profile' );
define( 'Profile', function (){
function Profile() {}
Profile.prototype.mockTrueLol = function() {
return true;
};
return Profile;
} );
require( [ 'mod' ], callbacks.add( function ( m ){
Mod = new m();
} ) );
} );
},
// tests here
} );
})();
Wednesday, March 27, 13
(function (){
TestJSTestDriver
var Mod;
AsyncTestCase( "TestJSTestDriver", {
setUp: function ( queue ){
queue.call( function ( callbacks ){
require.undef( 'Profile' );
define( 'Profile', function (){
function Profile() {}
Profile.prototype.mockTrueLol = function() {
return true;
};
return Profile;
} );
require( [ 'mod' ], callbacks.add( function ( m ){
Mod = new m();
} ) );
} );
},
// tests here
} );
})();
Wednesday, March 27, 13
(function (){
TestJSTestDriver
var Mod;
AsyncTestCase( "TestJSTestDriver", {
setUp: function ( queue ){
queue.call( function ( callbacks ){
require.undef( 'Profile' );
define( 'Profile', function (){
function Profile() {}
Profile.prototype.mockTrueLol = function() {
return true;
};
return Profile;
} );
require( [ 'mod' ], callbacks.add( function ( m ){
Mod = new m();
} ) );
} );
},
// tests here
} );
})();
Wednesday, March 27, 13
TestJSTestDriver
(function (){
var Mod;
AsyncTestCase( "TestJSTestDriver", {
// setUp here
tearDown: function (){
Mod = null;
},
"test Mod is setup": function (){
assertTrue( Mod.hasOwnProperty( 'boom' ) );
assertTrue( Mod.boom() );
}
} );
})();
Wednesday, March 27, 13
TestJSTestDriver
(function (){
var Mod;
AsyncTestCase( "TestJSTestDriver", {
// setUp here
tearDown: function (){
Mod = null;
},
"test Mod is setup": function (){
assertTrue( Mod.hasOwnProperty( 'boom' ) );
assertTrue( Mod.boom() );
}
} );
})();
Wednesday, March 27, 13
TestJSTestDriver
(function (){
var Mod;
AsyncTestCase( "TestJSTestDriver", {
// setUp here
tearDown: function (){
Mod = null;
},
"test Mod is setup": function (){
assertTrue( Mod.hasOwnProperty( 'boom' ) );
assertTrue( Mod.boom() );
}
} );
})();
// From Mod
this.boom = function () {
return (new Profile()).mockTrueLol();
};
Wednesday, March 27, 13
PHPStorm
Code and Compile Example
They all worked before, honest!
Wednesday, March 27, 13