Skip to content

Instantly share code, notes, and snippets.

@sranso
Last active August 29, 2015 14:08
Show Gist options
  • Save sranso/84efc2b4497df3f2eb9e to your computer and use it in GitHub Desktop.
Save sranso/84efc2b4497df3f2eb9e to your computer and use it in GitHub Desktop.

##AMD: what why how

###what

  • Asynchronous Module Definition
  • a format for writing modular js in the browser

###why

  • overall goal for the AMD format is to provide a solution for modular JavaScript that developers can use today
    • allows the browser to load multiple js bytes at the same time; wont get hung up on one thing (e.g. wont wait to load all of jquery before starting to load google analytics)
  • Provides a clear proposal for how to approach defining flexible modules.
  • Significantly cleaner than the present global namespace and <script> tag solutions many of us rely on. There's a clean way to declare stand-alone modules and dependencies they may have.
  • Module definitions are encapsulated, helping us to avoid pollution of the global namespace.
  • Works better than some alternative solutions (eg. CommonJS, which we'll be looking at shortly). Doesn't have issues with cross-domain, local or debugging and doesn't have a reliance on server-side tools to be used. Most AMD loaders support loading modules in the browser without a build process.
  • Provides a 'transport' approach for including multiple modules in a single file. Other approaches like CommonJS have yet to agree on a transport format.
  • It's possible to lazy load scripts if this is needed.

It is an improvement over the web's current "globals and script tags" because:

  • Uses the CommonJS practice of string IDs for dependencies. Clear declaration of dependencies and avoids the use of globals.
  • IDs can be mapped to different paths. This allows swapping out implementation. This is great for creating mocks for unit testing. For the above code sample, the code just expects something that implements the jQuery API and behavior. It does not have to be jQuery.
  • Encapsulates the module definition. Gives you the tools to avoid polluting the global namespace.
  • Clear path to defining the module value. Either use "return value;" or the CommonJS "exports" idiom, which can be useful for circular dependencies.

###how

  • two key concepts
    • the idea of a define method for facilitating module definition

      • define is used to define named or unnamed modules based on the proposal using the following signature
      • fetches a module
      define(
        module_id /*optional*/, 
        [dependencies] /*optional*/, 
        definition function /*function for instantiating the module or object*/
      );
      

      or

      define([
        'underscore'
      ], function(_) {
        // something with _
      });
      

      ^^ this uses requirejs

      • the dependencies argument represents an array of dependencies which are required by the module you are defining
      • the third argument ('definition function') is a function that's executed to instantiate your module
    • a require method for handling dependency loading

      • typically used to load code in a top-level JavaScript file or within a module should you wish to dynamically fetch dependencies
      • fetches a file
      require(['foo', 'bar'], function ( foo, bar ) {
        // rest of your code here
        foo.doSomething();
      });
      

###requirejs vs fs

  • fs loads non-js as well as js files. is asynchronous.
    • can create a read stream that reads chunks of info at a time while you load other things too. doesn't load the whole file into memory (while a synchronous call would). see this guy for more info.
  • require only loads js and is synchronous.

###examples

###resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment