Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using grunt concat, how would I automate the concatenation of the same file to many other files?

Tags:

concat

gruntjs

To concatenate two files, it looks something like this:

  concat: {
    src: ['common.js','js/app.js'],
    dest: 'assets/js/app.js'
  }

And if I want to concat an entire folder of files into one, it looks something like this:

  concat: {
    src: ['dev/*.js','],
    dest: 'prod/js/app.js'
  }

But let's say I have a file that I want to concat onto 10 or 20 other files, and I want them to concat separately? In other words, here is what I'm looking for:

A.js + B.js = AB.js
A.js + C.js = AC.js
A.js + D.js = AD.js
A.js + E.js = AE.js

And so on... To be more specific though, I can figure out how to concat files one by one as described, but I want to figure out how to specify A.js from the example, and have it concat onto any file in a specified path. So what I want is:

A.js + dev/*.js = AB.js, AC.js, AD.js, AE.js ...

In pseudo-code, here is what I want:

  concat: {
    src: ['common.js', 'dev/*.js','], // common.js gets concatenated to each file in this directory
    dest: 'prod/js/*.js' // each file in src gets saved separately in dest 
  }

I'd appreciate any help, I've have a hard time finding info on how to do this

like image 561
jonschlinkert Avatar asked Oct 04 '12 08:10

jonschlinkert


1 Answers

Grunt's built-in concat task (I recommend looking at the source btw) does not support anything like dest: 'prod/js/*.js', you would have to specify each output target separately which is an overkill in your case.

Your best bet is to just write your own code (perhaps wrap it in your custom task), it's quite simple. Here's a simple wrap multitask. Don't promise it's robust and safe to use :)

  grunt.registerMultiTask('wrap', 'Wraps source files with specified header and footer', function() {
        var data = this.data,
            path = require('path'),
            dest = grunt.template.process(data.dest),
            files = grunt.file.expandFiles(this.file.src),
            header = grunt.file.read(grunt.template.process(data.header)),
            footer = grunt.file.read(grunt.template.process(data.footer)),
            sep = grunt.utils.linefeed; 

        files.forEach(function(f) {
            var p = dest + '/' + path.basename(f),
                contents = grunt.file.read(f);

            grunt.file.write(p, header + sep + contents + sep + footer);
            grunt.log.writeln('File "' + p + '" created.');
        });
  });

Feed it with a config like this:

wrap: {
    html: {
        header: '<%= project.partials %>/head.html',
        footer: '<%= project.partials %>/footer.html',
        src: [
            '<%= project.pages %>/index.html',
            '<%= project.pages %>/about.html',
            '<%= project.pages %>/blog.html'
        ],
        dest: '.'   // destination *directory*, probably better than specifying same file names twice
    }
}

Just in case I also updated your fiddle: http://jsfiddle.net/dipish/hKkGX/

like image 73
Dmitry Pashkevich Avatar answered Oct 05 '22 02:10

Dmitry Pashkevich