Advertisement

More Related Content

Advertisement

Requirejs

  1. require.js a keynote information loader about a javascript module loader Wednesday, March 27, 13
  2. what is requires • a javascript module loader Wednesday, March 27, 13
  3. where to get it? • http://requirejs.org Wednesday, March 27, 13
  4. 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
  5. why do I need it? Wednesday, March 27, 13
  6. why do I need it? • Web sites are turning into Web apps Wednesday, March 27, 13
  7. why do I need it? • Web sites are turning into Web apps • Code complexity grows as the site gets bigger Wednesday, March 27, 13
  8. 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
  9. 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
  10. 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
  11. how does it solve this? Wednesday, March 27, 13
  12. how does it solve this? • Some sort of #include/import/require Wednesday, March 27, 13
  13. how does it solve this? • Some sort of #include/import/require • ability to load nested dependencies Wednesday, March 27, 13
  14. 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
  15. 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
  16. 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
  17. 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
  18. writing a module, today (function ($) { function Foo() { // do stuff here! } new Foo(); }(jQuery)); Wednesday, March 27, 13
  19. writing a module, today var $ = require('jquery'); exports.myExample = function () { // do stuff here! }; Wednesday, March 27, 13
  20. writing a module, today++: AMD define('mod',function(){ return function() { this.boom = function () { alert( 'Boom' ); }; } } ); Wednesday, March 27, 13
  21. What is AMD? • Asynchronous Module Definition Wednesday, March 27, 13
  22. 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
  23. why is this good? • Easy to test, because modules are compartmentalized • Dependency Injection Wednesday, March 27, 13
  24. amd still handles this (function () { this.myGlobal = function () {}; }()); Wednesday, March 27, 13
  25. require still supports normal javascript require(["some/script.js"], function() { //This function is called after some/script.js has loaded. }); Wednesday, March 27, 13
  26. It’s easy! • http://requirejs.org/docs/why.html Wednesday, March 27, 13
  27. 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
  28. Can run... • In the browser • In Node • In Rhino Wednesday, March 27, 13
  29. Using Closure Compiler • Means uses Java • Means using Rhino • r.js Wednesday, March 27, 13
  30. jscompile #!/bin/sh java -classpath /Users/jasonlotito/Downloads/rhino1_7R4/js.jar:/Users/ jasonlotito/Downloads/compiler-latest/compiler.jar org.mozilla.javascript.tools.shell.Main r.js -o $1 Wednesday, March 27, 13
  31. Getting the Compiler • http://requirejs.org/docs/download.html#rjs Wednesday, March 27, 13
  32. compiler java -classpath /Users/jasonlotito/Downloads/rhino1_7R4/js.jar:/Users/ jasonlotito/Downloads/compiler-latest/compiler.jar org.mozilla.javascript.tools.shell.Main r.js -o $1 Wednesday, March 27, 13
  33. compiler java -classpath /Users/jasonlotito/Downloads/rhino1_7R4/js.jar:/ Users/jasonlotito/Downloads/compiler-latest/compiler.jar org.mozilla.javascript.tools.shell.Main r.js -o $1 Wednesday, March 27, 13
  34. compiler java -classpath /Users/jasonlotito/Downloads/rhino1_7R4/js.jar:/Users/ jasonlotito/Downloads/compiler-latest/compiler.jar org.mozilla.javascript.tools.shell.Main r.js -o $1 Wednesday, March 27, 13
  35. compiler java -classpath /Users/jasonlotito/Downloads/rhino1_7R4/js.jar:/Users/ jasonlotito/Downloads/compiler-latest/compiler.jar org.mozilla.javascript.tools.shell.Main r.js -o $1 Wednesday, March 27, 13
  36. compiler java -classpath /Users/jasonlotito/Downloads/rhino1_7R4/js.jar:/Users/ jasonlotito/Downloads/compiler-latest/compiler.jar org.mozilla.javascript.tools.shell.Main r.js -o $1 Wednesday, March 27, 13
  37. compiler java -classpath /Users/jasonlotito/Downloads/rhino1_7R4/js.jar:/Users/ jasonlotito/Downloads/compiler-latest/compiler.jar org.mozilla.javascript.tools.shell.Main r.js -o $1 Wednesday, March 27, 13
  38. How to compile? • jscompile path/to/app.build.js Wednesday, March 27, 13
  39. What’s app.build.js ({ appDir: "../", baseUrl: "scripts/", dir: "../../webapp-build", optimize: "closure", paths: { "jquery": "empty:" }, modules: [ //Optimize the application files. jQuery is not //included since it is already in require-jquery.js { name: "main" } ], closure: { CompilerOptions: {}, CompilationLevel: 'SIMPLE_OPTIMIZATIONS', loggingLevel: 'WARNING' }, generateSourceMaps: true, preserveLicenseComments: false }) Wednesday, March 27, 13
  40. Alright stop... Let’s make sense of all these options by establishing our surroundings, namely, our project structure Wednesday, March 27, 13
  41. Our sample directory structure Wednesday, March 27, 13
  42. Our sample directory structure • r.js Wednesday, March 27, 13
  43. Our sample directory structure • r.js • webapp/ Wednesday, March 27, 13
  44. Our sample directory structure • r.js • webapp/ • app.html Wednesday, March 27, 13
  45. Our sample directory structure • r.js • webapp/ • app.html • scripts/ Wednesday, March 27, 13
  46. Our sample directory structure • r.js • webapp/ • app.html • scripts/ • app.build.js Wednesday, March 27, 13
  47. Our sample directory structure • r.js • webapp/ • app.html • scripts/ • app.build.js • app.build.dev.js Wednesday, March 27, 13
  48. Our sample directory structure • r.js • webapp/ • app.html • scripts/ • app.build.js • app.build.dev.js • main.js Wednesday, March 27, 13
  49. Our sample directory structure • r.js • webapp/ • app.html • scripts/ • app.build.js • app.build.dev.js • main.js • mod.js Wednesday, March 27, 13
  50. the app require( ["jquery", "mod"], function ( $, mod ) { var mod = new mod(); setTimeout( function () { mod.boom(); $( 'h1' ).text( 'Hey you guys!' ); }, 2000 ); setTimeout( function () { mod.boom(); $( 'h1' ).text( 'Baby, ruth?' ); }, 4000 ); setTimeout( function () { mod.boom(); $( 'h1' ).text( 'Truffle Shuffle' ); }, 6000 ); } ); Wednesday, March 27, 13
  51. the module define('mod',function(){ return function() { this.boom = function () { alert( 'Boom' ); }; } } ); Wednesday, March 27, 13
  52. modules can include other modules define('mod',['member/photos'],function(photos){ return function() { this.boom = function () { alert( 'Boom' ); photos.boom(); }; } } ); Wednesday, March 27, 13
  53. Compiled! whee! Wednesday, March 27, 13
  54. Compiled and minified via Closure Compiler (function(){define("mod",[],function(){return function(){this.boom=function() {alert("Boom")}}});require(["jquery","mod"],function(b,a){a=new a;setTimeout(function(){a.boom();b("h1").text("Hey you guys!")}, 2E3);setTimeout(function(){a.boom();b("h1").text("Baby, ruth?")}, 4E3);setTimeout(function(){a.boom();b("h1").text("Truffle Shuffle")}, 6E3)});define("main",function(){})})(); //@ sourceMappingURL=main.js.map Wednesday, March 27, 13
  55. Compiled with Source Maps closure: { CompilerOptions: {}, CompilationLevel: 'SIMPLE_OPTIMIZATIONS', loggingLevel: 'WARNING' }, generateSourceMaps: true, preserveLicenseComments: false Wednesday, March 27, 13
  56. .map file {"version":3, "file":"main.js", "lineCount":1, "mappings":"AAAC,SAAA,GACDA,MAAA,UAAgB,QAAA,SACP,SAAA,GACLC, SADK,CACOC,QAAAA,GAEVC,KAAA,QAFUD,CADP,CADO,CAAhB,CASA E,QAAA,kBAA4B,QAAA,CAAWC,CAAX,CAAcC,CAAd,EAEtBA,CAFsB,CAE hB,IAAIA,CAEdC,WAAA,CAAY,QAAA,GAEVD,CAAAL,KAAA,EACAI,EAAA, MAAAG,KAAA,iBAHU,CAAZ,KAMAD,WAAA,CAAY,QAAA,GAEVD,CAAAL, KAAA,EACAI,EAAA,MAAAG,KAAA,eAHU,CAAZ,KAMAD,WAAA,CAAY,QA AA,GAEVD,CAAAL,KAAA,EACAI,EAAA,MAAAG,KAAA,mBAHU,CAAZ,KAh B0B,CAA5B,CAwBAR,OAAA,QAAe,QAAA,IAAf,CAlCC,EAAA;", "sources":["main.js.src"], "names": ["define","boom","this.boom","alert","require","$","mod","setTimeout","text"]} Wednesday, March 27, 13
  57. testing define( 'mod', ['Profile'], function ( Profile ) { function mod() { this.boom = function () { return (new Profile()).mockTrueLol(); }; } return mod; } ); Wednesday, March 27, 13
  58. 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
  59. 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
  60. 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
  61. 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
  62. (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
  63. 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
  64. (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
  65. (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
  66. (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
  67. (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
  68. (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
  69. 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
  70. 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
  71. 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
  72. PHPStorm Code and Compile Example They all worked before, honest! Wednesday, March 27, 13
Advertisement