AMD - Why, What and How

6,386 views
6,259 views

Published on

AMD was put together by the JavaScript developer community in response to the wild west of coding styles and lack of standards.

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,386
On SlideShare
0
From Embeds
0
Number of Embeds
1,282
Actions
Shares
0
Downloads
103
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • AMD - Why, What and How

    1. 1. AMD - WHY, WHAT, AND HOWMike Wilcox - January2012Tweets: @clubajaxBlogs: clubajax.org
    2. 2. The Problem
    3. 3. The ProblemToday’s complex Web Apps have created theneed for:
    4. 4. The ProblemToday’s complex Web Apps have created theneed for: Structure Some sort of framework, to aid in rapid development
    5. 5. The ProblemToday’s complex Web Apps have created theneed for: Structure Some sort of framework, to aid in rapid development Object orientation To “black box” complex code
    6. 6. The ProblemToday’s complex Web Apps have created theneed for: Structure Some sort of framework, to aid in rapid development Object orientation To “black box” complex code Modules and packages RE: The 2,500 best jQuery plugins...
    7. 7. The ProblemToday’s complex Web Apps have created theneed for: Structure Some sort of framework, to aid in rapid development Object orientation To “black box” complex code Modules and packages RE: The 2,500 best jQuery plugins... Dependencies (includes, requires, imports, what-ev)
    8. 8. The ProblemToday’s complex Web Apps have created theneed for: Structure Some sort of framework, to aid in rapid development Object orientation To “black box” complex code Modules and packages RE: The 2,500 best jQuery plugins... Dependencies (includes, requires, imports, what-ev) Reusable code Scope-isolated, clean API, portable Globals are bad!
    9. 9. Single Files
    10. 10. Single Files The “old fashioned way” to write JavaScript was to do it all in a single file.
    11. 11. Single Files The “old fashioned way” to write JavaScript was to do it all in a single file. // define library ! var!noop = function(){ ! ! }, ! ! isEmpty = function(it){ ! ! ! for(var p in it){ ! ! ! ! return 0; ! ! ! } ! ! ! return 1; ! ! }, ! ! toString = {}.toString, ! ! isFunction = function(it){ ! ! ! return toString.call(it) == "[object Function]"; ! ! }, ! ! isString = function(it){ ! ! ! return toString.call(it) == "[object String]";
    12. 12. Single Files ! ! ! ! ! ! ! ! ! computeMapProg = function(map, dest, packName){ ! ! dest.splice(0, dest.length); var p, i, item, reverseName = 0; The “old fashioned way” to write JavaScript was to do ! ! ! ! for(p in map){ ! ! ! ! ! dest.push([p, map[p]]); it all in a single file. ! ! ! ! ! if(map[p]==packName){ ! ! ! ! ! ! reverseName = p; ! ! ! ! ! } ! ! ! ! } ! ! ! ! dest.sort(function(lhs, rhs){ ! ! ! ! ! return rhs[0].length - lhs[0].length; ! ! ! ! }); ! ! ! ! for(i = 0; i < dest.length;){ ! ! ! ! ! item = dest[i++]; ! ! ! ! ! item[2] = new RegExp("^" + item[0].replace(/([.$?*|{} ()[]/+^])/g, function(c){ return "" + c; }) + "(/|$)"); ! ! ! ! ! item[3] = item[0].length + 1; ! ! ! ! } ! ! ! ! return reverseName; ! ! ! }, ! ! ! fixupPackageInfo = function(packageInfo, baseUrl){ ! ! ! ! // calculate the precise (name, baseUrl, main, mappings) for a package ! ! ! ! var name = packageInfo.name; ! ! ! ! if(!name){
    13. 13. Single File - pros & cons
    14. 14. Single File - pros & cons Pros Fewer resources means faster load times.
    15. 15. Single File - pros & cons Pros Fewer resources means faster load times. No “build step” necessary.
    16. 16. Single File - pros & cons Pros Fewer resources means faster load times. No “build step” necessary.Cons Difficult to maintain and edit a file thousands of lines long. GOTO Line #
    17. 17. Single File - pros & cons Pros Fewer resources means faster load times. No “build step” necessary.Cons Difficult to maintain and edit a file thousands of lines long. GOTO Line # Code reusability is dirt poor. Copy and paste?
    18. 18. Single File - pros & cons Pros Fewer resources means faster load times. No “build step” necessary.Cons Difficult to maintain and edit a file thousands of lines long. GOTO Line # Code reusability is dirt poor. Copy and paste? Makes team development near impossible. GITMERGETOOL
    19. 19. Multiple Files
    20. 20. Multiple FilesMultiple files which follow an object oriented ornamespaced approach are easier to maintain becausethe brain more easily maps files to ideas.
    21. 21. Multiple FilesMultiple files which follow an object oriented ornamespaced approach are easier to maintain becausethe brain more easily maps files to ideas. [dom.js] [lang.js] library.dom = { library.lang = { // code // code } } [events.js] [string.js] library.events = library.string = { { // code // code } }
    22. 22. Multi File - pros & cons
    23. 23. Multi File - pros & cons Pros One-to-one, file-to-class makes organization easier.
    24. 24. Multi File - pros & cons Pros One-to-one, file-to-class makes organization easier. The brain more easily maps files to concepts (objects).
    25. 25. Multi File - pros & cons Pros One-to-one, file-to-class makes organization easier. The brain more easily maps files to concepts (objects). More team friendly.
    26. 26. Multi File - pros & cons Pros One-to-one, file-to-class makes organization easier. The brain more easily maps files to concepts (objects). More team friendly.Cons The files (and server requests) will add up fast and that will slow down the page.
    27. 27. Multi File - pros & cons Pros One-to-one, file-to-class makes organization easier. The brain more easily maps files to concepts (objects). More team friendly.Cons The files (and server requests) will add up fast and that will slow down the page. Lots of <script> tags. BLEAH.
    28. 28. Multi File - pros & cons Pros One-to-one, file-to-class makes organization easier. The brain more easily maps files to concepts (objects). More team friendly.Cons The files (and server requests) will add up fast and that will slow down the page. Lots of <script> tags. BLEAH. The system to track all these files and their order is YOU.
    29. 29. Web App with <script> tags
    30. 30. Web App with <script> tags
    31. 31. Web App with <script> tags
    32. 32. Build solution for <script> tags
    33. 33. Build solution for <script> tags Result can be fed into Google Closure Combiner, Dojo Shrinksafe, UglifyJS, etc, etc.
    34. 34. Dependency Matters
    35. 35. Dependency Matters Scripts load in this order[dom.js] [events.js]library.dom = { // code [lang.js] library.events =} { [string.js] library.lang = { // code } // code } library.string = { // code }
    36. 36. Dependency Matters Scripts load in this order A change is made to dom.js Adds events to node on create.[dom.js] [events.js]library.dom = { // code [lang.js] library.events =} { [string.js] library.lang = { // code } // code } library.string = { // code }
    37. 37. Dependency Matters Scripts load in this order A change is made to dom.js Adds events to node on create.[dom.js] [events.js]library.dom = { // code [lang.js] library.events =} { [string.js] dom.js is trying to access library.lang = { // code } // code events.js but it’s not loaded } library.string = yet { // code }
    38. 38. Dependency Management[dom.js] [events.js]library.dom = { // code [lang.js] library.events =} { [string.js] library.lang = { // code } // code } library.string = { // code }
    39. 39. Dependency Management [player.html][dom.js] [events.js]library.dom = { // code [admin.html] [lang.js] library.events =} { [string.js] library.lang = { // code } // code } library.string = { // code } [test.html]Now script order needsto be changed in all your
    40. 40. I thought Dojo had a build tool with dependency
    41. 41. Dojo’s <1.7 Solution
    42. 42. Dojo’s <1.7 Solution“provide” registers this page of code as “a class” (butactually just an object). dojo.provide(“dijit.Dialog”);
    43. 43. Dojo’s <1.7 Solution“provide” registers this page of code as “a class” (butactually just an object). dojo.provide(“dijit.Dialog”); dojo.require(“dijit.form.Button”); “require” tells Dojo that the provided code depends upon the required code. Dojo guarantees that the required code is loaded before the provided code is executed.
    44. 44. How Dojo <1.7 Worked
    45. 45. How Dojo <1.7 Worked Script files were pulled in as text with XHR. -= XHR =-[dom.js]codecodecoderequire(‘event’)library.dom = { // code}
    46. 46. How Dojo <1.7 Worked Script files were pulled in as text with XHR. One at a time, each text file is eval’d into JavaScript. synchronously! -= XHR =- -= EVAL =-[dom.js] [dom.js] [dom.js]code code codecode code codecode code coderequire(‘event’) require(‘event’) require(‘event’)library.dom = { library.dom = { library.dom = { // code // code // code} } }
    47. 47. Dojo <1.7 Problems
    48. 48. Dojo <1.7 Problems XHR load has same-origin restrictions
    49. 49. Dojo <1.7 Problems XHR load has same-origin restrictions Special, complex, XD loader was needed
    50. 50. Dojo <1.7 Problems XHR load has same-origin restrictions Special, complex, XD loader was needed Eval’d code totally fubar’d syntax-error line numbers
    51. 51. Dojo <1.7 Problems XHR load has same-origin restrictions Special, complex, XD loader was needed Eval’d code totally fubar’d syntax-error line numbers Synchronous XHR is very slow
    52. 52. Dojo <1.7 Problems XHR load has same-origin restrictions Special, complex, XD loader was needed Eval’d code totally fubar’d syntax-error line numbers Synchronous XHR is very slow Some environments do not allow eval (like Adobe AIR)
    53. 53. Dojo <1.7 Problems XHR load has same-origin restrictions Special, complex, XD loader was needed Eval’d code totally fubar’d syntax-error line numbers Synchronous XHR is very slow Some environments do not allow eval (like Adobe AIR) eval executes differently across browsers
    54. 54. Dojo <1.7 Problems XHR load has same-origin restrictions Special, complex, XD loader was needed Eval’d code totally fubar’d syntax-error line numbers Synchronous XHR is very slow Some environments do not allow eval (like Adobe AIR) eval executes differently across browsers Developers are taught that eval is evil
    55. 55. ALTERNATIVE LOADER TECHNIQUES
    56. 56. Async
    57. 57. Async var Employee = require("Employee"); function Manager () { } Manager.prototype = new Employee(); [ ERROR ]
    58. 58. Async var Employee = require("Employee"); function Manager () { } Manager.prototype = new Employee(); [ ERROR ]The Employee code is loaded async, so it happens inthe background while Manager is invoked, whichmeans Employee is not ready and an error occurs.
    59. 59. document.write
    60. 60. document.write write(‘<script src=”Store.js” />’); write(‘<script src=”Employee.js” />’);
    61. 61. document.write write(‘<script src=”Store.js” />’); write(‘<script src=”Employee.js” />’); No access to the script’s dependencies
    62. 62. document.write write(‘<script src=”Store.js” />’); write(‘<script src=”Employee.js” />’); No access to the script’s dependencies Does not work after page load
    63. 63. document.write write(‘<script src=”Store.js” />’); write(‘<script src=”Employee.js” />’); No access to the script’s dependencies Does not work after page load Blocks page rendering
    64. 64. appendChild(‘script’);
    65. 65. appendChild(‘script’); head = document.getElementsByTagName(head)[0]; script = document.createElement(script); script.src = url; head.appendChild(script); No access to the script’s dependencies
    66. 66. appendChild(‘script’); head = document.getElementsByTagName(head)[0]; script = document.createElement(script); script.src = url; head.appendChild(script); No access to the script’s dependencies Has same async issues
    67. 67. THE SOLUTION
    68. 68. Function Wrapping
    69. 69. Function Wrapping dependency dependency dependency code_for_loader_to_execute = function(){ return code_to_be_converted_to_module_later }
    70. 70. Function Wrapping dependency dependency dependency code_for_loader_to_execute = function(){ return code_to_be_converted_to_module_later } Wrapping code in function allows the loader to control when invocation needs to occur
    71. 71. Function Wrapping dependency dependency dependency code_for_loader_to_execute = function(){ return code_to_be_converted_to_module_later } Wrapping code in function allows the loader to control when invocation needs to occur All code can defer until after all dependencies are determined and loaded
    72. 72. AMD’s Methods
    73. 73. AMD’s Methods“define” registers this page of code as “a class”. define();
    74. 74. AMD’s Methods“define” registers this page of code as “a class”. define(); require(); “require” loads in the requested modules and provides them in a callback function.
    75. 75. Anatomy of AMD - define()
    76. 76. Anatomy of AMD - define() define( [ “./depA”, “./depB” ], function(depA, depB){ var myModule = {}; return myModule; } ); * There are other argument options, but these are the most common.
    77. 77. Anatomy of AMD - define()One of twoglobals used inthe spec define( [ “./depA”, “./depB” ], function(depA, depB){ var myModule = {}; return myModule; } ); * There are other argument options, but these are the most common.
    78. 78. Anatomy of AMD - define()One of two Dependencies list definedglobals used in as an array in the firstthe spec argument define( [ “./depA”, “./depB” ], function(depA, depB){ var myModule = {}; return myModule; } ); * There are other argument options, but these are the most common.
    79. 79. Anatomy of AMD - define()One of two Dependencies list definedglobals used in as an array in the firstthe spec argument The second define( [ argument is the “./depA”, Factory which is “./depB” consumed when ], function(depA, depB){ module is requested var myModule = {}; return myModule; } ); * There are other argument options, but these are the most common.
    80. 80. Anatomy of AMD - define()One of two Dependencies list definedglobals used in as an array in the firstthe spec argument The second define( [ argument is the “./depA”, Factory which is “./depB” consumed when ], function(depA, depB){ module is requested var myModule = {}; Dependencies return myModule; passed as factory’s } arguments ); * There are other argument options, but these are the most common.
    81. 81. Anatomy of AMD - define()One of two Dependencies list definedglobals used in as an array in the firstthe spec argument The second define( [ argument is the “./depA”, Factory which is “./depB” consumed when ], function(depA, depB){ module is requested var myModule = {}; Dependencies return myModule; passed as factory’s } arguments All of your module ); magic happens here, complete with scope isolation * There are other argument options, but these are the most common.
    82. 82. Anatomy of AMD - define()One of two Dependencies list definedglobals used in as an array in the firstthe spec argument The second define( [ argument is the “./depA”, Factory which is “./depB” consumed when ], function(depA, depB){ module is requested var myModule = {}; Dependencies return myModule; passed as factory’s } arguments All of your module); magic happens here, complete with scope isolationLooks like a class, smellslike a class... * There are other argument options, but these are the most common.
    83. 83. Anatomy of AMD - require()
    84. 84. Anatomy of AMD - require() require( [ “library/depA”, “library/depB” ], function(depA, depB){ depA.doSomething(); depB.someMore(); } ); * There are other argument options, but these are the most common.
    85. 85. Anatomy of AMD - require()The other global require( [ “library/depA”, “library/depB” ], function(depA, depB){ depA.doSomething(); depB.someMore(); } ); * There are other argument options, but these are the most common.
    86. 86. Anatomy of AMD - require() Modules, or “Imports” listThe other global defined as an array in the first argument require( [ “library/depA”, “library/depB” ], function(depA, depB){ depA.doSomething(); depB.someMore(); } ); * There are other argument options, but these are the most common.
    87. 87. Anatomy of AMD - require() Modules, or “Imports” listThe other global defined as an array in the first argument require( Callback fires when [ modules are loaded “library/depA”, “library/depB” and ready ], function(depA, depB){ depA.doSomething(); depB.someMore(); } ); * There are other argument options, but these are the most common.
    88. 88. Anatomy of AMD - require() Modules, or “Imports” listThe other global defined as an array in the first argument require( Callback fires when [ modules are loaded “library/depA”, “library/depB” and ready ], function(depA, depB){ depA.doSomething(); Modules passed as depB.someMore(); callback’s } arguments ); * There are other argument options, but these are the most common.
    89. 89. Anatomy of AMD - require() Modules, or “Imports” listThe other global defined as an array in the first argument require( Callback fires when [ modules are loaded “library/depA”, “library/depB” and ready ], function(depA, depB){ depA.doSomething(); Modules passed as depB.someMore(); callback’s } arguments ); Modules are ready to access here * There are other argument options, but these are the most common.
    90. 90. Anatomy of AMD - require() Modules, or “Imports” listThe other global defined as an array in the first argument require( Callback fires when [ modules are loaded “library/depA”, “library/depB” and ready ], function(depA, depB){ depA.doSomething(); Modules passed as depB.someMore(); callback’s } arguments ); Modules are ready to access hereLooks like “define”! Simple! * There are other argument options, but these are the most common.
    91. 91. Why is ASYNC fast anyway?
    92. 92. Why is ASYNC fast anyway?In this context, “async” refers to allowing the browserto load the scripts natively. It can load many scripts atonce, concurrently.
    93. 93. Why is ASYNC fast anyway?The “sync” loader needed to block all other processeswhile a script was loaded.
    94. 94. EXTENDING AMD
    95. 95. Plugins
    96. 96. PluginsThe bang! symbol represents a plugin thatperforms a special task. require(["dojo", "dojo/domReady!"], function(dojo){ ! doDomStuff(); }); define([ “dijit/Widget”, “dojo/text!myTemplate.html” ], function(Widget, template){ // build a widget });
    97. 97. PluginsThe bang! symbol represents a plugin thatperforms a special task. domReady! is a common plugin that prevents the callback from firing until the DOM is in fact... ready. require(["dojo", "dojo/domReady!"], function(dojo){ ! doDomStuff(); }); define([ “dijit/Widget”, “dojo/text!myTemplate.html” ], function(Widget, template){ // build a widget });
    98. 98. PluginsThe bang! symbol represents a plugin thatperforms a special task. domReady! is a common plugin that prevents the callback from firing until the DOM is in fact... ready. require(["dojo", "dojo/domReady!"], function(dojo){ ! doDomStuff(); }); define([ “dijit/Widget”, “dojo/text!myTemplate.html” ], function(Widget, template){ // build a widget }); text! knows that it is reading text or HTML and possibly applies transforms to it.
    99. 99. Build Tools
    100. 100. Build ToolsA “profile” is the description file the Dojo Builder uses.The AMD structure works well as individual files or asone combined file. var profile = { ! releaseDir:"../clubajax-deploy", ! packages:[ ! ! { ! ! ! name:"clubajax", ! ! ! location:"." ! ! },{ ! ! ! name:"plugin", ! ! ! location:"../plugin" ! ! } ! ], ! layers:{ ! ! "clubajax/layer":{ ! ! ! include:[ custom/main, plugin/main ] ! ! } ! } };
    101. 101. Packages
    102. 102. PackagesA package.json file will help describe your code, itsexternal dependencies, and how it should be used. { "name": "clubajax.js", "description": "Club AJAX Base Library", "licenses": [{ "type": "AFLv2.1", "url": "http://dojo/LICENSE" }], "bugs": "", "keywords": [], "homepage": "http://clubajax.org/", "dependencies": {}, "dojoBuild": "clubajax.profile.js", "main": "./main"
    103. 103. PackagesA package.json file will help describe your code, itsexternal dependencies, and how it should be used. { "name": "clubajax.js", "description": "Club AJAX Base Library", "licenses": [{ "type": "AFLv2.1", "url": "http://dojo/LICENSE" }], "bugs": "", "keywords": [], "homepage": "http://clubajax.org/", "dependencies": {}, "dojoBuild": "clubajax.profile.js", "main": "./main"“dojoBuild” points to the profile, and “main” points tothe master file that knows of all the files in thepackage.
    104. 104. RESOURCES
    105. 105. AMD Authors
    106. 106. AMD Authors James Burke Original Dojo Loader author Developed RequireJS and spearheaded AMD
    107. 107. AMD Authors
    108. 108. AMD Authors Kevin Dangoor Authored blog post: “What Server Side JavaScript Needs” Founded CommonJS Expressed the need for JS modules and packages RequireJS based on CommonJS module spec
    109. 109. AMD Authors
    110. 110. AMD Authors Rawld Gill Wrote the Dojo 1.7 loader and Node.js build tool key contributor to AMD spec Authored all AMD plugins (text, i18n, domReady, ready) dojo bootstrap (kernel and base load) dojos has.js implementation (enhanced from standard version)
    111. 111. AMD Authors
    112. 112. AMD Authors Kris Zyp Of course he helped. What is there that Kris Zyp DOESN’T do??
    113. 113. AMD LibrariesThe following libraries are either AMD-compliant or AMD loaders jQuery 1.7 Dojo 1.7 MooTools 2.0 EmbedJS curl.js
    114. 114. More AMD Info https://github.com/amdjs/amdjs-api/wiki/AMD http://www.commonjs.org/ http://www.commonjs.org/specs/ http://dojotoolkit.org/reference-guide/loader/ index.html#loader-index http://dojotoolkit.org/reference-guide/loader/amd.html#loader- amd http://arstechnica.com/web/news/2009/12/commonjs-effort- sets-javascript-on-path-for-world-domination.ars http://requirejs.org/docs/history.html http://www.commonjs.org/history/ https://groups.google.com/group/amd-implement?pli=1✴ Special credit to Rawld Gill of Alto Visio for his in depth explanations of Dojo Loader and Build Tool✴ And a very special credit to James Burke - since most of the information in this presentation came from the RequireJS pages.
    115. 115. Description

    ×