Using Grunt with requirejs

When using the grunt-contrib-requirejs module, it takes a lot of time to compile the final file. I needed a solution a quicker solution which uses grunt copy to copy files from bower modules folder to my target assets directory.

I can do this manually but I have to update 2 files each time I add a new requirejs dependency; I have to include it in main.js and also in the Gruntfile.js.. That’s a lot of work 🙁

So I finally came up with this approach that does those process above: A nice snippet that allows faster requirejs development.

In the main.js I have a sctructure like this:

require.config({
    paths: {
        /* jQuery */
        'jquery': '../../.build/bower_components/jquery/dist/jquery.min',

I want this to become:

require.config({
    paths: {
        /* jQuery */
        'jquery': 'vendor/jquery.min',

Also, I need the files to be copied to the vendor folder. So In the Gruntfile.js I have:

module.exports = function (grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        www: "../theme/",
        bower: "bower_components/",
        assets: "../.assets/",
        jsFromBower: "",
...
...
// Update paths in main.js
replace: {
    mainjs: {
        options: {
            patterns: [
                {
                    match: /..\/..\/.build\/bower_components\/.*\//mg,
                    replacement: 'vendor/'
                }
            ]
        },
        files: [
            {
                expand: true,
                flatten: true,
                src: ['<%= assets %>scripts/main.js'],
                dest: '<%= www %>assets/scripts/'
            }
        ]
    }
},
...

...
/**
* The dev task.
*
* It checks the main.js file to get bower_components and replaces the entries
* inside of the main.js file. This allows quicker theme developpement.
*/
grunt.registerTask('dev', 'description', function () {
var path = require('path'),
files = 0,
www = grunt.config.get('www'),
assets = grunt.config.get('assets'),
mainjs = grunt.file.read(assets + 'scripts/main.js'),
regexPattern = /(bower_components\/.*)'/gm,
matchArray;

/**
* Loop the main.js file: Since our regular expression uses the "g" flag,
* we can use the exec() method multiple times to find successive matches
* in the same string
*/
while ((matchArray = regexPattern.exec(mainjs)) !== null) {
if (matchArray.index === regexPattern.lastIndex) {
regexPattern.lastIndex++;
}

var filePath = matchArray[1] + '.js',
file = path.basename(filePath);
grunt.file.copy(filePath, www + 'assets/scripts/vendor/' + file);

files++;
}
//grunt.config.set('jsFromBower', files.join())

grunt.log.ok('Coppied ' + files + ' js scripts from "bower_components" to "theme/assets/scripts/vendor/"');

grunt.task.run(['imagemin', 'copy', 'replace', 'compass:dev', 'cssmin', 'watch']);
});

Perfect!