Skip to content

Instantly share code, notes, and snippets.

@davidensinger
Last active August 29, 2015 14:08
Show Gist options
  • Save davidensinger/4c9a06f2e547b458e089 to your computer and use it in GitHub Desktop.
Save davidensinger/4c9a06f2e547b458e089 to your computer and use it in GitHub Desktop.
Example Gruntfile.js for Five Good Reasons to Use Grunt for Front End CQ Development
'use strict';
module.exports = function (grunt) {
// Show elapsed time after tasks run
require('time-grunt')(grunt);
// Load all Grunt tasks
require('load-grunt-tasks')(grunt);
grunt.initConfig({
// Configurable paths
pathTo: {
jcrRoot: 'project-name-core/project-name-core-ui/src/main/content/jcr_root/',
projectDesigns: 'etc/designs/project-name/'
},
// use grunt-dev-update to check for out of date dependencies
devUpdate: {
check: {
options: {
reportUpdated: false,
updateType: 'report'
}
}
},
// clean the generated icons directory that’s used with grunticon
clean: {
icons: ['<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>static/icons/dist/']
},
// compile project’s CSS
less: {
build: {
files:{
'<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>clientlibs/css/dist/application.css':
'<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>clientlibs/css/source/application.less'
}
}
},
// add vendor prefixes to CSS
autoprefixer: {
options: {
browsers: [
'last 2 versions',
'safari 6',
'ie 8',
'ie 9',
'opera 12.1',
'ios 6',
'android 4'
]
},
build: {
files:{
'<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>clientlibs/css/dist/application.css':
'<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>clientlibs/css/dist/application.css'
}
},
},
// minify CSS
cssmin: {
build: {
files:{
'<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>clientlibs/css/dist/application.min.css':
'<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>clientlibs/css/dist/application.css'
}
}
},
// minify SVGs
svgmin: {
options: {
plugins: [
{
removeViewBox: false
}, {
removeUselessStrokeAndFill: false
}
]
},
build: {
files: [{
expand: true,
cwd: '<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>static/icons/source/raw/',
src: ['*.svg'],
dest: '<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>static/icons/source/compressed/'
}]
}
},
// optimize images
imagemin: {
build: {
files: [{
expand: true,
cwd: '<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>static/img/source',
src: ['**/*.{png,jpg,gif}'],
dest: '<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>static/img/dist'
}]
}
},
grunticon: {
build: {
files: [{
expand: true,
cwd: '<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>static/icons/source/compressed/',
src: ['*.svg'],
dest: '<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>static/icons/dist/'
}]
}
},
// concatenate our JS
concat: {
options: {
separator: ';'
},
build: {
src: ['<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>clientlibs/js/source/**/*.js'],
dest: '<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>clientlibs/js/dist/application.js'
}
},
// uglify our JS to reduce file size
uglify: {
build: {
files: {
'<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>clientlibs/js/dist/application.min.js': ['<%= concat.build.dest %>']
}
}
},
// lint our JS
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: ['<%= pathTo.jcrRoot %><%= pathTo.projectDesigns %>clientlibs/js/source/**/*.js']
},
watch: {
author: {
files: ['<%= pathTo.jcrRoot %>**/*.{css,xml,html,js,jsp,txt}'],
tasks: ['slang:author'],
options: {
spawn: false
}
},
publish: {
files: ['<%= pathTo.jcrRoot %>**/*.{css,xml,html,js,jsp,txt}'],
tasks: ['slang:publish'],
options: {
spawn: false
},
},
less: {
files: ['<%= pathTo.jcrRoot %>**/*.less'],
tasks: ['less','autoprefixer']
},
js: {
files: ['<%= jshint.all %>'],
tasks: ['jshint']
}
},
concurrent: {
options: {
logConcurrentOutput: true
},
author: [
'watch:less',
'watch:js',
'watch:author'
],
publish: [
'watch:less',
'watch:js',
'watch:publish'
]
},
slang: {
author: {
options: {
port: '4502'
}
},
publish: {
options: {
port: '4503'
}
}
}
});
grunt.event.on('watch', function(action, filepath, target) {
grunt.config.set(['slang', 'author', 'src'], filepath);
grunt.config.set(['slang', 'publish', 'src'], filepath);
});
grunt.registerTask('check', ['devUpdate','newer:jshint']);
grunt.registerTask('css', ['less', 'autoprefixer', 'cssmin']);
grunt.registerTask('icons', ['clean:icons', 'svgmin', 'grunticon', 'images']);
grunt.registerTask('images', ['newer:imagemin']);
grunt.registerTask('js', ['newer:jshint', 'concat', 'uglify']);
grunt.registerTask('assets', ['css', 'icons', 'images', 'js']);
grunt.registerTask('author', ['concurrent:author']);
grunt.registerTask('publish', ['concurrent:publish']);
grunt.registerTask('default', ['concurrent:author']);
};
@davidensinger
Copy link
Author

If you get this error (“Fatal error: spawn EMFILE”) on any of the watch tasks then you may need to be more specific about which file formats and directories you’re watching. If you’re on OSX you may also try running this command to increase your ulimit: ulimit -n 10240.

@davidensinger
Copy link
Author

Troubleshoot your tasks by including the --verbose (or -v) flag, which will output additional information about them.

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