Created
September 3, 2011 16:20
-
-
Save millermedeiros/1191420 to your computer and use it in GitHub Desktop.
Example of how to use a single JS file for multiple pages of an application
This file contains 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Example</title> | |
<meta name="description" content="This is just an example"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<link rel="stylesheet" href="css/main.css"> | |
</head> | |
<body data-modules="foobar, lorem/ipsum"> | |
<div id="wrapper"> | |
Just an example | |
</div> | |
<script data-main="js/main.js" src="js/lib/require/require.js"></script> | |
</body> | |
</html> |
This file contains 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
// main.js is used only for settings and initializing application, | |
// all heavy logic is stored inside proper modules, it makes it | |
// easy to require core modules from inside the application and | |
// also keeps main.js small since settings adds too much noise | |
// to the real code. | |
// | |
// see: http://blog.millermedeiros.com/2011/05/single-entry-point-ftw/ | |
// SETTINGS ======== | |
require.config({ | |
paths : { | |
'jquery' : 'lib/jquery/jquery' | |
} | |
}); | |
// INIT APP ======== | |
define( | |
[ | |
// "require" as depencency so paths are relative to | |
// current context | |
'require', | |
'jquery', | |
'someOtherModuleUsedByAllPages' | |
], | |
function(require, $, someSharedModule){ | |
function init(){ | |
// if metadata on HTML grab it and do a require | |
// body have a `data-modules="foo, bar/ipsum, dolor"` | |
var modules = $('body').data('modules') || ''; | |
if(modules){ | |
require(modules.split(/\s*,\s*/), function(){ | |
// do something when they finish loading, I usually | |
// make this kind of module to auto-instantiate, | |
// so we wouldn't need to do anything here | |
}); | |
} | |
// depending on the project it may be better to simply try | |
// to match a className instead of adding each module to | |
// a data-attribute: | |
if( $('.my-awesome-calendar').length ){ | |
require(['widgets/myAwesomeCalendar']); | |
} | |
someSharedModule.init(); | |
} | |
// if you use URLs to find modules there is no need to wait | |
// for DOM-ready to start loading modules if you have too | |
// many paths it is better to create some sort of look-up | |
// table or use a routing system like crossroads.js to | |
// simplify the logic | |
switch(document.location.pathname){ | |
case '/foo': | |
require(['sections/foo/main'], initSection); | |
break; | |
case '/foo/bar': | |
require(['sections/foo/main'], initSection); | |
break; | |
default: | |
//let's just assume we have a lot of pages with common features | |
require(['sections/simplePage'], initSection); | |
} | |
function initSection(section){ | |
section.init(); | |
} | |
//init app on domready | |
$(document).ready(init); | |
} | |
); |
This file contains 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
// This module is only used to decide which section should be loaded and | |
// initialized. | |
// This example is just to demonstrate how Crossroads.js can simplify | |
// the process of loading AMD modules on demand. It assumes it is a | |
// regular website but the same technique could be used for single page | |
// apps with very small teaks. | |
// --- | |
// Author: Miller Medeiros | |
// https://gist.github.com/1191420 | |
define(['crossroads'], function(crossroads){ | |
// ROUTES ==== | |
var newsDetail = crossroads.addRoute('/news/{id}', loadSection); | |
newsDetail.rules = { | |
id : /^\d+$/, //should be numeric | |
//normalize value to return proper module path (which isn't an URL param) | |
normalize_ : function(request, params){ | |
return [ 'news/article', params.id ]; | |
} | |
}; | |
var jobsDetail = crossroads.addRoute('/jobs/{id}/:title:'); | |
jobsDetail.rules = { | |
id : /^\d+$/ //should be numeric | |
}; | |
//we can also use the `SignalBinding.params` to set a default param (same | |
//effect as using `rules.normalize_`). | |
var jobsDetailBinding = jobsDetail.matched.add(loadSection); | |
jobsDetailBinding.params = ['jobs/detail']; | |
var basicSection = crossroads.addRoute('/{section}', loadSection); | |
basicSection.rules = { | |
section : ['news', 'jobs', 'home', 'contact'] //valid sections | |
}; | |
// METHODS ==== | |
function loadSection(path, rest_params){ | |
var params = Array.prototype.slice.call(arguments, 1); | |
//I'm just assuming all sections modules are stored inside a folder | |
//called "sections" and that each section/sub-section have a "main.js" | |
//file. | |
//It's important to note that r.js won't inline these dependencies | |
//automatically since module names are generated dynamically, use the | |
//"includes" build setting or optimize each section individually. | |
require(['sections/'+ path +'/main'], function(mod){ | |
mod.init.apply(mod, params); | |
}); | |
} | |
//if it was a single page app we would probably create a public method to | |
//navigate between sections and also dispose previous section before | |
//initializing the new one, but that is outside the scope of this example. | |
// INIT ==== | |
//parse current URL to decide what to do | |
crossroads.parse(document.location.pathname); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I Miller,
For each module, the required path should be specified means like ,Account-->Account-->Creaeate accounts