Skip to content

Instantly share code, notes, and snippets.

@dariocravero
Created December 14, 2012 21:47
Show Gist options
  • Save dariocravero/4288937 to your computer and use it in GitHub Desktop.
Save dariocravero/4288937 to your computer and use it in GitHub Desktop.
// This is the main application configuration file. It is a Grunt
// configuration file, which you can learn more about here:
// https://github.com/cowboy/grunt/blob/master/docs/configuring.md
module.exports = function(grunt) {
'use strict';
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-jst');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-mincss');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-md5');
grunt.loadTasks('tasks');
grunt.initConfig({
pkg: function() { return grunt.file.readJSON('fingerprinted.json'); },
// The lint task will run the build configuration and the application
// JavaScript through JSHint and report any errors. You can change the
// options for this task, by reading this:
// https://github.com/cowboy/grunt/blob/master/docs/task_lint.md
jshint: {
files: [
"build/config.js", "require.config.js", "app/**/*.js"
],
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
boss: true,
eqnull: true,
browser: true,
// The jshint option for scripturl is set to lax, because the anchor
// override inside main.js needs to test for them so as to not accidentally
// route.
scripturl: true,
globals: {
require: true,
define: true,
requirejs: true,
describe: true,
expect: true,
it: true
}
}
},
// The jst task compiles all application templates into JavaScript
// functions with the underscore.js template function from 1.2.4. You can
// change the namespace and the template options, by reading this:
// https://github.com/gruntjs/grunt-contrib/blob/master/docs/jst.md
//
// The concat task depends on this file to exist, so if you decide to
// remove this, ensure concat is updated accordingly.
jst: {
"dist/debug/templates.js": [
"app/templates/**/*.html"
],
options: {
templateSettings: {
// We use mustache-like instead of ERB-like templates.
interpolate: /\{\{(.+?)\}\}/g
}
}
},
// This task uses James Burke's excellent r.js AMD build tool. In the
// future other builders may be contributed as drop-in alternatives.
requirejs: {
// Include the main configuration file.
mainConfigFile: "app/config.js",
// Also include Bower's configuration file.
packagesConfig: "require.config.js",
// Output file.
out: "dist/debug/require.js",
// Root application module.
name: "config",
// Do not wrap everything in an IIFE.
wrap: false
},
// The concatenate task is used here to merge the almond require/define
// shim and the templates into the application code. It's named
// dist/debug/require.js, because we want to only load one script file in
// index.html.
concat: {
dist: {
src: [
"components/almond/almond.js",
"dist/debug/templates.js",
"dist/debug/require.js"
],
dest: "dist/debug/require.js",
separator: ";"
}
},
// This task uses the MinCSS Node.js project to take all your CSS files in
// order and concatenate them into a single CSS file named index.css. It
// also minifies all the CSS as well. This is named index.css, because we
// only want to load one stylesheet in index.html.
mincss: {
"dist/release/alvaromatias.css": [
"../../public/stylesheets/h5bp.css",
"../../public/stylesheets/animate.css",
"../../public/stylesheets/application.css"
]
},
// Takes the built require.js file and minifies it for filesize benefits.
uglify: {
"dist/release/alvaromatias.js": [
"dist/debug/require.js"
],
"dist/release/modernizr.js": [
"components/modernizr/modernizr.js"
]
},
// Add asset fingerprinting
md5: {
compile: {
files: {
"../../public": ["dist/release/alvaromatias.js", "dist/release/modernizr.js", "dist/release/alvaromatias.css"]
},
options: {
callback: function(newPath, oldPath) {
var config, configFile = './fingerprinted.json',
path = require('path'), fingerprintedAsset, asset;
// FIXME, it might not be like that, i.e., the path might be something else
fingerprintedAsset = path.basename(newPath);
asset = path.basename(oldPath);
try {
config = require(configFile);
} catch (e) {
config = {files: {}};
}
config.files[asset] = '/' + fingerprintedAsset;
grunt.file.write(configFile, JSON.stringify(config, null, 4));
},
keepBasename: true,
keepExtension: true
}
}
},
// GZip assets
compress: {
zip: {
files: {
'../../public<%= pkg().files["alvaromatias.js"] %>.gz': '../../public<%= pkg().files["alvaromatias.js"] %>',
'../../public<%= pkg().files["modernizr.js"] %>.gz': '../../public<%= pkg().files["modernizr.js"] %>',
'../../public<%= pkg().files["alvaromatias.css"] %>.gz': '../../public<%= pkg().files["alvaromatias.css"] %>'
},
level: 9
}
},
// Lint files automatically if watching...
watch: {
files: "<config:jshint.files>",
tasks: "jshint"
},
// The clean task ensures all files are removed from the dist/ directory so
// that no files linger from previous builds.
clean: {
all: ['dist']
}
});
// The debug task will remove all contents inside the dist/ folder, lint
// all your code, precompile all the underscore templates into
// dist/debug/templates.js, compile all the application code into
// dist/debug/require.js, and then concatenate the require/define shim
// almond.js and dist/debug/templates.js into the require.js file.
grunt.registerTask("debug", ["clean", "jshint", "jst", "requirejs", "concat"]);
// The release task will run the debug tasks and then minify the
// dist/debug/require.js file and CSS files.
grunt.registerTask("release", ["debug", "uglify", "mincss", "md5", "compress"]);
};
{
"name": "backbone-boilerplate",
"version": "0.1.0",
"dependencies": {
"requirejs": "2.1.1",
"grunt": "~0.4",
"grunt-contrib-clean": "latest",
"grunt-contrib-compress": "latest",
"grunt-contrib-concat": "latest",
"grunt-contrib-copy": "latest",
"grunt-contrib-jshint": "latest",
"grunt-contrib-jst": "latest",
"grunt-contrib-mincss": "latest",
"grunt-contrib-uglify": "latest",
"grunt-md5": "latest"
}
}
/*
* Grunt Task File
* ---------------
*
* Task: RequireJS
* Description: Tasks for working with RequireJS.
* Dependencies: requirejs
*
*/
module.exports = function(grunt) {
// TODO: ditch this when grunt v0.4 is released
grunt.util = grunt.util || grunt.utils;
// Node.js modules
var fs = require("fs");
var path = require("path");
// Include requirejs
var requirejs = require("requirejs");
var _ = grunt.util._;
// Shorthand Grunt functions
var log = grunt.log;
grunt.registerTask("requirejs", "Build a RequireJS project.", function(prop) {
var options = grunt.config("requirejs") || {};
var done = this.async();
// Merge passed options into defaults
options = _.extend({}, {
// Do not optimize
optimize: "none",
// Show warnings
logLevel: 2,
// Ensure modules are inserted
skipModuleInsertion: false,
// JamJS configuration file
packagesConfig: "require.config.js"
}, options);
if (fs.existsSync(process.cwd() + "/" + options.packagesConfig)) {
_.extend(options, require(process.cwd() + "/" + options.packagesConfig));
}
// Run r.js
requirejs.optimize(options, function(response) {
// Print out response
log.writeln(response);
done();
});
});
grunt.registerTask("list", "Show module dependencies", function(prop) {
var options = grunt.config("requirejs") || {};
var baseUrl = options.baseUrl || "app";
// ensure trailing slash
// grunt.helper("list", path.normalize(baseUrl + "/"));
});
// TODO Replace helpers with whatever works for Grunt 0.4.x
// grunt.registerHelper("list", function(appDir) {
// var jsRegExp = /\.js$/;
// requirejs.tools.useLib(function(require) {
// require(["parse"], function(parse) {
// var deps = {};
// var files = [];
// // Recursively find all files inside the application directory
// function recurse(dir) {
// fs.readdirSync(dir).forEach(function(name) {
// var subdir = path.resolve(dir, name);
// var stats = fs.statSync(subdir);
//
// if (stats.isDirectory()) {
// recurse(subdir);
// } else if (jsRegExp.test(name)) {
// files.push(subdir);
// }
// });
// }
// // Start with the app directory e.g. app/
// recurse(appDir);
// files.forEach(function(name) {
// var contents = fs.readFileSync(name, "utf8");
// var shortname = name.slice(name.indexOf(appDir));
// deps[shortname] = parse.findDependencies(name,
// contents);
// });
//
// console.log(grunt.helper("tree", deps));
// });
// });
// });
// grunt.registerHelper("tree", function(obj) {
// var tree = [""];
// function spaces(len, end, start) {
// start = start || " ";
// end = end || " ";
// if (!start) {
// return Array(len+1).join(Array(3).join(end));
// } else {
// return Array(len+1).join(start + Array(2).join(end));
// }
// }
// function traverse(obj, depth) {
// _.each(obj, function(val, key) {
// var len;
// if (_.isArray(val)) {
// tree.push("\u251c" + spaces(depth) + " " + key);
// len = val.length;
// _.each(val, function(val, i) {
// if (_.isString(val)) {
// if (i == len-1) {
// tree.push("\u2502 " + spaces(depth+1, "\u2500", "\u2514") + " "
// + val);
// } else {
// tree.push("\u2502 " + spaces(depth+1, "\u2500", "\u251c") + " "
// + val);
// }
// } else if (_.isObject(val)) {
// traverse(obj, depth+1);
// }
// });
// tree.push("\u2502");
// } else if (_.isObject(val)) {
// tree.push(spaces(depth) + key);
// traverse(val, depth+1);
// } else {
// tree.push(spaces(depth) + key);
// }
// });
// }
// traverse(obj, 0);
// tree.pop();
// return tree.join("\n");
// });
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment