Skip to content

Instantly share code, notes, and snippets.

@gfranko gfranko/
Last active Oct 12, 2015

What would you like to do?
Backbone-Require-Boilerplate (BRB) Mobile and Desktop Build Configuration with almond.js
// Node.js - Require.js Build Script
// To run the build type the following: node
// Loads the Require.js Optimizer
var requirejs = require('../public/js/libs/r.js');
// Sets up the basic configuration
var baseConfig = {
// All modules are located relative to this path
baseUrl: "../public/js/",
// Sets path names and paths for modules relative to the baseUrl
paths: {
"mobile": "app/config/MobileInit",
"desktop": "app/config/DesktopInit"
// Wraps all scripts in an IIFE (Immediately Invoked Function Expression)
// (function() { + content + }());
wrap: true,
// The optimized build file will use almond.js (AMD shim) instead of the larger Require.js
name: "libs/almond",
// Removes third-party license comments
preserveLicenseComments: false,
// Uses uglify.js for minification
optimize: "uglify"
// Creates an array of build configs, the baseConfig will
// be mixed into both the mobile and desktop builds below.
var configs = [
// Tells Require.js to look at mobileInit.js for all mobile shim and path configurations
mainConfigFile: "../public/js/app/config/MobileInit.js",
// Points to mobileInit.js (Remember that "mobile" is the module name for mobileInit.js)
include: ["mobile"],
// The optimized mobile build file will put into the app directory
out: "../public/js/app/config/MobileInit.min.js"
// Tells Require.js to look at desktopInit.js for all desktop shim and path configurations
mainConfigFile: "../public/js/app/config/DesktopInit.js",
// Points to desktopInit.js (Remember that "desktop" is the module name for desktopInit.js)
include: ["desktop"],
// The optimized desktop build file will put within the app directory
out: "../public/js/app/config/DesktopInit.min.js"
// Function used to mix in baseConfig to a new config target
function mix(target) {
for (var prop in baseConfig) {
if (baseConfig.hasOwnProperty(prop)) {
target[prop] = baseConfig[prop];
return target;
//Create a runner that will run a separate build for each item
//in the configs array. Thanks to @jwhitley for this cleverness
var runner = configs.reduceRight(function(prev, currentConfig) {
return function (buildReportText) {
requirejs.optimize(mix(currentConfig), prev);
}, function(buildReportText) {
console.log("Building... this might take a few seconds");
//Run the builds
<!doctype html>
<!-- -->
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7 ui-mobile-rendering" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8 ui-mobile-rendering" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9 ui-mobile-rendering" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js ui-mobile-rendering" lang="en"> <!--<![endif]-->
<meta charset="utf-8">
<!-- Use the .htaccess and remove these lines to avoid edge case issues.
More info: -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Backbone-Require Boilerplate</title>
<meta name="description" content="Backbone.js and Require.js Boilerplate Library">
<!-- Mobile viewport optimized: -->
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, width=device-width">
<!--Detect if the browser is a mobile browser or a desktop browser and conditionally include your JavaScript -->
// Mobile/Desktop Detection script
(function(ua, w, d, undefined) {
// App Environment
// ---------------
// Tip: Set to false to turn on "development" mode
var production = true,
// Configuration object that will contain the correct prod/dev CSS and JavaScript files to load
config = {}
// Listen to the DOMContentLoaded Event (Supported in IE9+, Chrome Firefox, Safari)
w.addEventListener("DOMContentLoaded", function() {
// Mobile/Tablet Logic
if((/iPhone|iPod|iPad|Android|BlackBerry|Opera Mini|IEMobile/).test(ua)) {
// Mobile/Tablet CSS and JavaScript files to load
config = {
// CSS files that are loaded when in development mode
"dev-css": ["css/libs/"],
// CSS files that are loaded when in production mode
"prod-css": ["css/libs/"],
// JavaScript files that are loaded when in development mode
"dev-js": [{ "data-main": "js/app/config/MobileInit.js", "src": "js/libs/require.js" }],
// JavaScript files that are loaded when in production mode
"prod-js": ["js/app/config/MobileInit.min.js"]
// Desktop Logic
else {
// Desktop CSS and JavaScript files to load
config = {
// Loaded when not in production mode
"dev-css": ["css/libs/bootstrap.css"],
// Loaded when in production mode
"prod-css": ["css/libs/bootstrap.min.css"],
// Loaded when not in production mode
"dev-js": [{ "data-main": "js/app/config/DesktopInit.js", "src": "js/libs/require.js" }],
// Loaded when in production mode
"prod-js": ["js/app/config/DesktopInit.min.js"]
// Loads the correct CSS and JavaScript files
loadFiles(config, function() {
// After both the mobile css and Require.js are loaded, the css file used for both mobile and desktop is loaded
// Loaded when not in production mode
"dev-css": ["css/commonstyles.css"],
// Loaded when in production mode
"prod-css": ["css/commonstyles.min.css"]
function loadCSS(urls, callback) {
var x, link;
for(x = 0; x <= urls.length - 1; x += 1) {
link = d.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = urls[x];
if(callback) callback();
function loadJS(files, callback) {
var x, script, file
for(x = 0; x <= files.length - 1; x += 1) {
file = files[x];
script = d.createElement('script');
if(((typeof file).toLowerCase()) === "object" && file["data-main"] !== undefined) {
script.setAttribute("data-main", file["data-main"]);
script.src = file.src;
else {
script.src = file;
if(callback) callback();
function loadFiles(obj, callback) {
if(production) {
// Loads the production CSS file(s)
loadCSS(obj["prod-css"], function() {
// If there are production JavaScript files to load
if(obj["prod-js"]) {
// Loads the correct initialization file (which includes Almond.js)
loadJS(obj["prod-js"], callback);
// Else if your app is in development mode
else {
// Loads the development CSS file(s)
loadCSS(obj["dev-css"], function() {
// If there are development Javascript files to load
if(obj["dev-js"]) {
// Loads Require.js and tells Require.js to find the correct intialization file
loadJS(obj["dev-js"], callback);
}, false);
})(navigator.userAgent || navigator.vendor || window.opera, window, window.document);
<div data-role="page">
<header data-role="header" class="navbar nav navbar-inner">
<h1>Backbone-Require-Boilerplate (BRB)</h1>
</header> <!-- /header -->
<div class="container-fluid" data-role="content">
<div class="row-fluid">
<div class="span12">
<div class="example"></div>
<footer class="footer navbar navbar-fixed-bottom" data-role="footer">
<p>Written by <a href="" target="_blank">Greg Franko</a></p>
</footer><!-- /footer -->
</div> <!-- /page -->

This comment has been minimized.

Copy link
Owner Author

gfranko commented Sep 19, 2012

This script is based on this gist by James Burke

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.