For this I use grunt-filerev for the versionning and grunt-usemin for the automatic update of the references in source files.
These two modules works well together (usemin replacing references with a mapping provided by filerev)
Hope this helps
edit: a few code examples (only showing you what's interesting in your case):
I use usemin & filerev only when packaging my app (for deployment) :
In the head of my index.html, the following code tell usemin to take all the files between the build
tag and agregate it into one named ie-shims.js
[...]
<!-- build:js /js/ie-shims.js -->
<script src="/vendor/html5shiv/dist/html5shiv.js"></script>
<script src="/vendor/respond/dest/respond.src.js"></script>
<!-- endbuild -->
[...]
Next, in my gruntfile.js, i have two node :
[...]
filerev: {
options: {
encoding: 'utf8',
algorithm: 'md5',
length: 8
},
source: {
files: [{
src: [
'www/js/**/*.js',
'www/assets/**/*.{jpg,jpeg,gif,png,ico}'
]
}]
}
},
useminPrepare: {
html: 'src/index.html',
options: {
dest: 'www'
}
},
// usemin has access to the revved files mapping through grunt.filerev.summary
usemin: {
html: ['www/*.html'],
css: ['www/css/**/*.css'],
js: ['www/js/**/*.js'],
options: {
dirs: ['www'],
assetsDirs: ['www'],
patterns: {
js: [
[/["']([^:"']+\.(?:png|gif|jpe?g))["']/img, 'Image replacement in js files']
]
}
}
} [...]
Finally, I have a grunt task that put all that together :
grunt.registerTask('build', 'Build task, does everything', ['useminPrepare', 'filerev', 'usemin']);
Then, the generated HTML is like that :
[...]
<script src="/js/ie-shims.9f790592.js"></script>
[...]