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.jsin 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 defineto wrap logic that you would like to re-use somewhere else in your application
- 
            Use requirewhen 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 definewrapper 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