Skip to content

Instantly share code, notes, and snippets.

@millermedeiros
Created September 23, 2011 14:33
Show Gist options
  • Select an option

  • Save millermedeiros/1237496 to your computer and use it in GitHub Desktop.

Select an option

Save millermedeiros/1237496 to your computer and use it in GitHub Desktop.
Another example of single entry point with RequireJS + individual section/module versioning
({
//settings for the r.js optimizer
baseUrl : '../js',
name : 'main',
out : '../deploy/js/main-v2.js', //here you can set the versioning
excludes : [
//so we can load those modules only when needed, also to make sure
//individual versioning of sections also work as expected.
'sections/search/main',
'sections/news/main',
//if you want to version jquery using the paths config it shouldn't be
//included by any module...
'jquery'
],
includes : [
//everything that is shared across multiple pages and may not be on the
//dependency list of any module loaded directly by main.js
'sections/simplePage',
'some/dynamic/module'
]
})
({
//optimizing each module individually since we want to version each module
//indivually, if no versioning required could optimize whole project at
//once.
baseUrl : '../js',
name : 'sections/search/main',
out : '../deploy/js/sections/search/main-v27.js', //here you can set the versioning
excludes : [
//simplePage was already included into main.js and it is loaded by all
//pages..
'sections/simplePage',
//if you want to version jquery using the paths config it shouldn't be
//included by any module...
'jquery'
]
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Example</title>
</head>
<body data-page="search">
<h1>Search page</h1>
<script src="js/lib/require.js"></script>
<script>
require.config{
baseUrl : 'js',
paths : {
// all versioning paths alias here since it shouldn't be cached
'main' : 'main-v2',
'sections/search/main' : 'sections/search/main-v27',
'jquery' : 'lib/jquery.1.6.3'
}
};
require(['main'], function(main){
//main is loaded, probably don't need to do anything here..
});
</script>
</body>
</html>
// ===== js/main.js ====== //
//other settings you may need:
require.config({
//set everything besides the alias to versioned modules
});
define(['require', 'jquery', 'foo/bar'], function(require, $, bar){
function init(){
//"foo/bar" is used by all pages
bar.init();
loadPageDependencies();
}
function loadPageDependencies(){
//assuming we have a [data-page] attr on the body
var curPage = $.trim( $('body').data('page') );
switch(curPage){
case 'contact':
case 'about':
//in case you have many pages that load same dependencies just
//create a module that contain everything you may need
require(['sections/basicPage'], initSection);
break;
case 'search':
//since search is very specific we create a module that contain
//all the code that it needs.
require(['sections/search/main'], initSection);
break;
case 'news':
require(['sections/news/main'], initSection);
break;
case 'home':
//I would probably create a new module "sections/home/main.js"
// otherwise main.js can start growing too much, smaller
// modules are easier to understand, done this way just as
// example if you have some page that is very simple and don't
// think it is worth the touble of creating a separate module
// for it...
require(['sections/basicPage', 'widgets/SlideShow', 'widgets/FancyMap'], function(basicPage, SlideShow, FancyMap){
basicPage.init();
Slideshow.build('.slideshow-container');
FancyMap.build('.map-container');
});
break;
}
}
// it's better to manually call the init method that way we only start the
// section if needed, if modules are optimized into a single file it would
// cause conflicts since all the "define callbacks" will get executed.
function initSection(section){
section.init();
}
$(document).ready(init);
});
//===== js/sections/search/main.js ======= //
//note that it also loads "sections/basicPage.js", it's better to a module list
//all it's dependencies and not require that any other code gets executed
//before.. you shouldn't rely on the `require` call inside "main.js" to provide
//everythign the page need, it will be easier to update later if page don't
//need the "sections/basicPage" module later or you decide to switch to
//a "sections/complePage-B"...
define(['jquery', 'sections/basicPage', 'foo', 'widgets/SearchInputField'], function($, basicPage, foo, SearchInputField){
var _input;
function init(){
//initialize section
basicPage.init();
foo.doSomething();
_input = new SearchInputField();
}
//... some other code would go here ...
//API
return {
//all sections should have an init method
init : init
};
});
@millermedeiros
Copy link
Author

I use the main.js file as the only entry point because then I can load things that are shared across all the pages and initialize what needs to be initialized by all the pages - like settings and basic functionality (all pages probably have the same main navigation, etc..) - depending on your project structure it may be simpler to just use a basic require directly on the HTML and create a new module for each page type, like:

<script>
  require(['sections/search/main'], function(section){
    section.init();
  });
</script>

I prefer to keep all the logic on the JS side so I can use the same HTML template for all the pages.. more info: http://blog.millermedeiros.com/2011/05/single-entry-point-ftw/

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