Created
July 25, 2012 17:35
-
-
Save bennadel/3177438 to your computer and use it in GitHub Desktop.
Creating A Lazy Loading Utility Module For RequireJS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Define the module. | |
| define( | |
| [ | |
| "require" | |
| ], | |
| function( require ){ | |
| // Define the states of loading for a given set of modules | |
| // within a require() statement. | |
| var states = { | |
| unloaded: "UNLOADED", | |
| loading: "LOADING", | |
| loaded: "LOADED" | |
| }; | |
| // Define the top-level module container. Mostly, we're making | |
| // the top-level container a non-Function so that users won't | |
| // try to invoke this without calling the once() method below. | |
| var lazyRequire = {}; | |
| // I will return a new, unique instance of the requrieOnce() | |
| // method. Each instance will only call the require() method | |
| // once internally. | |
| lazyRequire.once = function(){ | |
| // The modules start in an unloaded state before | |
| // requireOnce() is invoked by the calling code. | |
| var state = states.unloaded; | |
| var requireOnce = function( dependencies, loadCallback, runCallback ){ | |
| // Use the module state to determine which method to | |
| // invoke (or just to ignore the invocation). | |
| if (state === states.loaded){ | |
| // Invoke the run callback - the modules have | |
| // been loaded. | |
| runCallback(); | |
| // The modules have not yet been requested - let's | |
| // lazy load them. | |
| } else if (state === states.unloaded){ | |
| // We're about to load the modules asynchronously; | |
| // flag the interim state. | |
| state = states.loading; | |
| // Load the modules. | |
| require( | |
| dependencies, | |
| function(){ | |
| // Invoke the load callback with the | |
| // loaded module definitions so that the | |
| // calling code can use the module | |
| // defitions to lazily initialize code. | |
| loadCallback.apply( null, arguments ); | |
| // Update the state - the modules have | |
| // been loaded and the calling code has | |
| // been initialized. | |
| state = states.loaded; | |
| // Explicitly invoke the run callback | |
| // since we always want to use the modules | |
| // after they have first been loaded. | |
| runCallback(); | |
| } | |
| ); | |
| // RequireJS is currently loading the modules | |
| // asynchronously, but they have not finished | |
| // loading yet. | |
| } else { | |
| // Simply ignore this call. | |
| return; | |
| } | |
| }; | |
| // Return the new lazy loader. | |
| return( requireOnce ); | |
| }; | |
| // -------------------------------------------------- // | |
| // -------------------------------------------------- // | |
| // Return the module definition. | |
| return( lazyRequire ); | |
| } | |
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Set up the paths for the application. | |
| requirejs.config({ | |
| paths: { | |
| "domReady": "lib/require/domReady", | |
| "jquery": "lib/jquery/jquery-1.7.2.min", | |
| "templates": "templates", | |
| "text": "lib/require/text", | |
| "utils": "utils", | |
| "views": "views" | |
| } | |
| }); | |
| // Run the scripts when the DOM-READY event has fired. | |
| require( | |
| [ | |
| "jquery", | |
| "utils/lazyRequire", | |
| "domReady!" | |
| ], | |
| function( $, lazyRequire ){ | |
| // Since the Help / FAQ module is probably going to be rarely | |
| // used by the user, I don't want to bother loading it as | |
| // part of the initial page load. As such, I'll lazy-load it | |
| // when the "launch" link is clicked. | |
| (function(){ | |
| // Our FAQ module will start out as null until loaded. | |
| // And, it's not loaded until it's first needed. | |
| var faq = null; | |
| var body = $( "body" ); | |
| var launchFaq = $( "p.m-help a" ); | |
| var requireOnce = lazyRequire.once(); | |
| // Bind the click handler. This handler will lazy-load | |
| // the FAQ module when it is first requested. | |
| launchFaq.click( | |
| function( event ){ | |
| event.preventDefault(); | |
| // Run require once, the first time; then, use | |
| // the "run" callback for each subsequent require | |
| // invocation. | |
| requireOnce( | |
| [ | |
| "views/faq" | |
| ], | |
| function( FAQ ){ | |
| faq = new FAQ(); | |
| }, | |
| function(){ | |
| faq.open( body ); | |
| } | |
| ); | |
| } | |
| ); | |
| })(); | |
| } | |
| ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment