node.jsgruntjsgrunt-contrib-uglify

How to uglify multiple .js files in a folder and output them to a different folder?


I'm new to grunt, and I can't figure out how to define paths when using the plugin grunt-contrib-uglify-es.

This is my folder structure :

.
├── controllers
├── models
├── public
│   ├── build
│   │   ├─ foo.min.js
│   │   └─ x.min.js
│   ├── css
│   ├── font
│   └── js
│        ├─ foo.js
│        └─ x.js
├── routes
├── tests
├── utils
└── views

and this is my grunt task :

// take all js file in public/js/ and put them in public/build/
uglify: {
  options: {
    mangle: false,
          banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
  },
  build: {
    files: [{
      expand: true,
      src: 'public/js/*.js',
      dest: 'public/build/',
      rename: function (dst, src) {
        console.log(dst);
        console.log(src);
        return src;
      }
    }]
  }
}

When I run grunt, it creates the file(s) into public/js and overwrites the existing file(s). I don't understand why.

I also tried this :

expand: true,
src: 'js/*.js',
dest: 'build/',
cwd: 'public/',

And now it create a new folder js at the root with all the files inside.

I would like to compress every .js file in public/js/ and then put them in public/build/

I'm clearly lost, can you help me please?


Solution

  • To meet your requirement, when building the files object dynamically you need to utilize;

    1. The cwd option - which is described as follows:

      • cwd All src matches are relative to (but don't include) this path.
    2. The rename function, which is described as:

      rename Embeds a customized function, which returns a string containing the new destination and filename. This function is called for each matched src file (after extension renaming and flattening).

    Gruntfile:

    The following configuration will meet your desired result.

    module.exports = function (grunt) {
    
      grunt.loadNpmTasks('grunt-contrib-uglify-es');
    
      grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        uglify: {
          options: {
            mangle: false,
            banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
          },
          build: {
    
            // Change your configuration to this...
            files: [{
              expand: true,
              cwd: 'public/js',
              src: '*.js',
              dest: 'public/build/',
              rename: function (dst, src) {
                return dst + '/' + src.replace('.js', '.min.js');
              }
            }]
          }
        }
      });
    
      grunt.registerTask('default', ['uglify']);
    };