Reputation: 31
I'm trying to run my development/prototyping environment (not a blog) using Jekyll, Haml, Sass and host it on GitHub Pages.
Locally, I use Grunt.js to compile HAML, SASS and serve/build Jekyll.
While my Gruntfile.js is able to do my tasks, it's extremely slow as I try to run the build and serve concurrently.
Any Grunt experts can point me to the right direction on how to optimize my Grunt config so it can run faster? Thanks!
Below is my current config:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jekyll: {
options: {
src : './',
dest: './_gh_pages',
config: '_config.build.yml' // avoid the relative baseurl issue
},
serve: {
options: {
serve: true,
port: 9001
}
},
dev: {
}
},
compass: {
dev: {
options: {
config: 'config.rb',
force: true
}
}
},
haml: {
includes: {
expand: true,
cwd: 'haml/includes/',
src: ['*.haml'],
dest: '_includes/',
ext: '.html'
},
layouts: {
expand: true,
cwd: 'haml/layouts/',
src: ['*.haml'],
dest: '_layouts/',
ext: '.html'
},
pages: {
expand: true,
cwd: 'haml/',
src: ['*.haml'],
dest: './',
ext: '.html'
}
},
watch: {
options: {
atBegin: true
},
sass: {
files: ['sass/**/*.scss'],
tasks: ['compass:dev']
},
haml: {
files: ['haml/**/*.haml'],
tasks: ['haml:includes', 'haml:layouts', 'haml:pages']
},
jekyll: {
files: ['./**/*.html', './**/*.css'],
tasks: ['jekyll:dev']
}
},
concurrent: {
target: {
tasks: ['jekyll:serve', 'watch'],
options: {
logConcurrentOutput: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-html-validation');
grunt.loadNpmTasks('grunt-jekyll');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-haml');
grunt.loadNpmTasks('grunt-concurrent');
grunt.registerTask('default', ['concurrent:target']);
Upvotes: 2
Views: 3214
Reputation: 11597
I haven’t used Grunt
with haml
or jekyll
, but I use it on a daily basis to manage several projects, using different packages as needed.
It’s hard to tell how complex or how big your application is just by looking at your Gruntfile.js
, but I would definitely start by making tasks a bit smarter. The watch
task is usually the one I put most attention on, because that’s preferably the only task that should run upon saving files. For instance if you save a .scss
file, only the compass:dev
task is fired up. If you save a .js
file, the tasks jshint
, jasmine
and uglify:dev
would fire up. That keeps the development wheel turning only where it’s needed, and Grunt
completing tasks faster.
Another thing I don’t see in your Gruntfile.js
is dedicated tasks for dev
and dist
, which can be a good practice. An example:
// Start web server
grunt.registerTask('serve', [
'connect:livereload',
'watch'
]);
// Compile production files
grunt.registerTask('dist', [
'jshint',
'jasmine',
'uglify:dist',
'compass:dist'
]);
// Compile developer friendly environment
grunt.registerTask('dev', [
'jshint',
'jasmine',
'uglify:dev',
'compass:dev',
'connect:livereload'
]);
// Default task(s).
grunt.registerTask('default', 'dev’);
Use $ grunt serve
on one shell to start a local server and watch the app. To make full builds without relying on the watch
task, run $ grunt
to make a full dev
build (because that’s the default task on this example) or run $ grunt dist
to make a production-ready build.
So my advice is to rely on the watch
task while developing, and running do-it-all tasks sparingly. Grunt
’s beauty is not only on multi-tasking, but also on tasking-on-demand. Running full builds on each and every file save is possible, but is not efficient.
BTW, your jekyll
task within watch
is empty, because jekyll:dev
is empty:
jekyll: {
files: ['./**/*.html', './**/*.css'],
tasks: ['jekyll:dev']
}
Hope it helps!
Upvotes: 4