This can be done using the grunt-contrib-copy plugin.
The main thing to note is that you can change the destination programmatically by using a rename function (which takes in the destination and source of each file).
Here is a (somewhat brittle) sample Gruntfile.js
that should copy to your desired structure:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
copy: {
main: {
files: [
{
expand: true,
cwd: 'src/modules/',
src: ['**/*.js'],
dest: 'dev/js/',
rename: function(dest, src) {
// use the source directory to create the file
// example with your directory structure
// dest="dev/js/"
// src="https://stackoverflow.com/questions/15271121/module1/js/main.js"
return dest + src.substring(0, src.indexOf("https://stackoverflow.com/")) + '.js';
}
},
{
expand: true,
cwd: 'src/modules/',
src: ['**/*.scss'],
dest: 'dev/css/',
rename: function(dest, src) {
return dest + src.substring(0, src.indexOf("https://stackoverflow.com/")) + '.css';
}
},
{
expand: true,
cwd: 'src/modules/',
src: ['**/*.html'],
dest: 'dev/',
rename: function(dest, src) {
return dest + src.substring(0, src.indexOf("https://stackoverflow.com/")) + '.html';
}
}
]
}
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
// Default task(s).
grunt.registerTask('default', ['copy']);
};