58

there are some js files in static/js/

    1. a.js
    2. b.js
    3. c.js   

how to config grunt.js to get below files:

    1. a.min.js
    2. b.min.js
    3. c.min.js

as far, I have to type specific file name:

  min: {
    dist: {
    src:  'js/**/*.js',
    dest: 'js/min/xxx.min.js'
   }
 }
Pranav 웃
  • 8,469
  • 6
  • 38
  • 48
looping
  • 1,141
  • 3
  • 11
  • 20
  • 1
    Currently there is no out-of-the box support for this (see [How to minify separate files and do not combine them into one file?](https://github.com/gruntjs/grunt/issues/481)). You'll have to generate configuration for min task dynamically (with lots of targets) or create your own task that uses min helper... I'll try to post a solution later... – Dmitry Pashkevich Nov 16 '12 at 12:59
  • 1
    @DmitryPashkevich I'm not sure I agree. You can run several many tasks within the min task. See my answer below. – DavidHyogo Feb 02 '13 at 10:24
  • 1
    @DavidHyogo the question was, *how to **not** have to manually enlist all the files but have a configuration like Inge one in the original question work* – Dmitry Pashkevich Feb 02 '13 at 13:43
  • *Inge = the (predictive text, sorry :)) – Dmitry Pashkevich Feb 02 '13 at 14:17
  • @DmitryPashkevich Thanks Dmitry. You understood the question better than I did. Strictly speaking, the question didn't really say that, even though you got it, so I've edited it to make the question clearer. I'll leave my answer because it is useful for simple use cases, but I can see how useful it would be to be able to do a whole directory the way the questioner intended. – DavidHyogo Feb 02 '13 at 14:25
  • @looping Most of my edits have been removed in the 2nd edit. The question is once again unclear and full of strange unnatural English. – DavidHyogo Feb 25 '13 at 15:22

11 Answers11

53

Had the same problem and found a solution that would automatically minify all my scripts separately:

uglify: {
      build: {
        files: [{
            expand: true,
            src: '**/*.js',
            dest: 'build/scripts',
            cwd: 'app/scripts'
        }]
      }
    }
Frank Parent
  • 2,136
  • 19
  • 33
  • 1
    Can u explain exactly which property stands for what cuz it didn't work for me. – LoneWOLFs Aug 21 '13 at 12:36
  • 1
    @LoneWOLFs refer to http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically for info on these. Also note the wrapping [] are essential, even for a single files declaration. – Oli Studholme Nov 04 '13 at 05:54
  • 1
    cwd stands for current working directory , I think anyone uses this snippet should be aware of it's directory structure , I personally removed the cwd and it worked – Milad Jul 09 '15 at 04:23
  • Is there a possibility to change the filenames? Current solution will preserve them, afaik. What about changing `*.js` to `*.min.js` dynamically? – skip405 Aug 01 '15 at 12:53
  • 1
    Just add `ext: '.min.js',` to the list inside `files` to output .min.js copies of the files – Daniel Tonon Jan 20 '16 at 10:07
23

In grunt 0.4 you can specify multiple dest/src pairs like this:

uglify: {
    dist: {
        files: {
            'dist/main.js': 'src/main.js',
            'dist/widget.js': 'src/widget.js'
        }
    }
}
Sindre Sorhus
  • 62,972
  • 39
  • 168
  • 232
  • 4
    Some people should find expandMapping (http://gruntjs.com/api/grunt.file#grunt.file.expandmapping) useful, so a whole directory can be minified and its structure kept intact, without listing every JS file inside. – Greg Mar 02 '13 at 06:59
  • You can also compile pairs of multiple files into one minified file like so: files: { 'dist/main.js': 'src/main/*.js', 'dist/widget.js': 'src/widget/*.js' } – Baraa Jun 07 '15 at 06:49
17

Or you can use expandMapping, like this:

min: {
    files: grunt.file.expandMapping(['path/*.js', 'path2/*.js'], 'destination/', {
        rename: function(destBase, destPath) {
            return destBase+destPath.replace('.js', '.min.js');
        }
    })
}

And the output:

path/test.js => destination/path/test.min.js
path2/foo.js => destination/path2/foo.min.js

Rafa Heringer
  • 320
  • 2
  • 4
  • This is great, however, if `.min.js` files already exist in those directories, it will create `.min.min.js` files and so on everytime this is ran. How to avoid this? – Solomon Closson Jul 27 '20 at 05:13
15

This below gruntjs works for me for creating minified files for all the js files under a dir

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
    build: {
        files: [{
            expand: true,
            src: '**/*.js',
            dest: 'build/scripts',
            cwd: 'public_html/app',
        ext: '.min.js'
        }]
      }
    }
  });

  // Load the plugin that provides the "uglify" task.
  grunt.loadNpmTasks('grunt-contrib-uglify');

  // Default task(s).
  grunt.registerTask('default', ['uglify']);

};
Sharmila
  • 151
  • 1
  • 2
6

From the grunt docs for min:

This task is a multi task, meaning that grunt will automatically iterate over all min targets if a target is not specified.

So you can do this:

  min: {
    min_a: {
       src:  'a.js',
       dest: 'a.min.js'
    },
    min_b: {
       src:  'b.js',
       dest: 'b.min.js'
    },
    min_c: {
       src:  'c.js',
       dest: 'c.min.js'
 }

There's nothing special about the name 'dist' for these tasks.

DavidHyogo
  • 2,838
  • 4
  • 31
  • 48
  • 2
    The OP wants to use wildcards to include all files. Doing it this way requires that you name every individual file. – Noremac Mar 27 '15 at 15:08
4

Use the ext option to name the files .min.js instead of .js

uglify: {
      build: {
        files: [{
            expand: true,
            src: '**/*.js',
            dest: 'build/scripts',
            cwd: 'app/scripts',
            ext: '.min.js'
        }]
      }
    }
Blowsie
  • 40,239
  • 15
  • 88
  • 108
4

For explicitly export some files into separate output files (in this case all.min.js and all.jquery.js) use:

uglify: {
  js: {
    files : {
        'js/all.min.js' : [
          'js/modernizr.js',
          'js/vendor/modernizr-2.6.2-respond-1.1.0.min.js',
          'js/bootstrap.min.js',
          'js/main.js',
          'js/ZeroClipboard.min.js',
          'js/bootstrap-datepicker/bootstrap-datepicker.js'
        ],

        'js/all.jquery.js' : [
          'js/vendor/jquery-1.9.1.js',
          'js/vendor/jquery-migrate-1.2.1.js',
          'js/vendor/jquery-ui.js'
        ]

    }
  },
  options: {
    banner: '\n/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n',
    preserveComments: 'some',
    report: 'min'
  }
},
lubosdz
  • 4,210
  • 2
  • 29
  • 43
1

I like to keep the original files and also create uglified ones:

uglify: {
  dist: {
    files: [{
      expand: true,
      src: '**/*.js',
      dest: 'destdir',
      cwd: 'srcdir',
      rename: function(dest, src) { return dest + '/' + src.replace('.js', '.min.js'); }
    }]
  }
},
redgeoff
  • 3,163
  • 1
  • 25
  • 39
  • This is the answer I was looking for. I have some files that end with something like '.pkgd.js' so if I go with the `ext` option everyone else suggests this gets overwritten and breaks my application. This is the most solid answer in my opinion as it does exactly what we want. – ESR May 09 '16 at 23:36
0

You also can use copy and grunt-mindirect.

copy: {
  dist: {
    src: 'a.js',
    dest: 'a.min.js'
  }
},
minidirect: {
  all: 'js/min/*.min.js'
}

This should work.

Charles
  • 11,367
  • 10
  • 77
  • 114
0

I guess it only matters for watch tasks.

In grunt 0.4 you can do this

  var filesA = 'a.js', filesB = 'b.js', filesC = 'c.js';

  ...

  min: {
      min_a: {
         src:  filesA,
         dest: 'a.min.js'
      },
      min_b: {
         src:  filesB,
         dest: 'b.min.js'
      },
      min_c: {
         src:  filesC,
         dest: 'c.min.js'
  }

  watch: {
      min_a: {
         files:  filesA,
         tasks: ['min:min_a']
      },
      min_b: {
         files:  filesB,
         tasks: ['min:min_b']
      },
      min_c: {
         files:  filesC,
         tasks: ['min:min_c']
      }
  }

After that just start grunt watch and all will be fine automagically.

bullgare
  • 1,643
  • 1
  • 21
  • 32
0

In an intention to help others who come to this page in future -

I came across a video which explains on how to minify JS files using Grunt JS here: https://www.youtube.com/watch?v=Gkv7pA0PMJQ

The source code is made available here: http://www.techcbt.com/Post/359/Grunt-JS/how-to-minify-uglify-javascript-files-using-grunt-js

Just in case, if the above links are not working:

  1. You can minify all javascript files and combine/concat into one file using the following script:

    module.exports = function(grunt){
 grunt.loadNpmTasks('grunt-contrib-uglify'); 
 
 grunt.initConfig({
  pkg: grunt.file.readJSON('package.json'),

  uglify:{
   t1:{
    files:{
     'dest/all.min.js': ['src/app.js', 'src/one.js', 'src/t/two.js']
    }
   }
  }
 }); 
};
  1. If you would like to have source maps also generated, you can enable "sourceMap" option as follows:

    module.exports = function(grunt){
 grunt.loadNpmTasks('grunt-contrib-uglify'); 

 grunt.initConfig({
  pkg: grunt.file.readJSON('package.json'),

  uglify:{
   t1:{
    options : {
           sourceMap : true,
         },
    files:{
     'dest/all.min.js': ['src/app.js', 'src/one.js', 'src/t/two.js']
    }
   }
  }
 }); 
};
  1. In order to retain entire folder structure while minifying JS files, you can use the following script:

    module.exports = function(grunt){
 grunt.loadNpmTasks('grunt-contrib-uglify'); 

 grunt.initConfig({
  pkg: grunt.file.readJSON('package.json'),

  uglify:{
   t1:{
    files: [{
     cwd: 'src/',
                 src: '**/*.js',  
                 dest: 'dest/',    
                 expand: true,    
                 flatten: false,
                 ext: '.min.js'
             }]
   }
  }
 }); 
};
PCoughlin
  • 153
  • 10
user203687
  • 6,875
  • 12
  • 53
  • 85