Remi
Remi

Reputation: 5357

grunt environment specific options for a task

In order to keep the gruntfile DRY I would like to change options based on the environment I'm running a grunt task for.

So for instance if I want to use two grunt tasks:

grunt.task.run('uglify:production');
grunt.task.run('uglify:development');

I would like them both to compile the same files, however with different options.

uglify: {

  production: {
    options: {
      compress: true
    }
  }

  development: {
    options: {
      compress: false,
      beautify: true
    }
  }

  // rather not redeclare these files twice
  files: {

    vendor: {
      // this name should change based on the environment
      'dest/vendor-output.js': ['src/vendor-input1.js', 'src/vendor-input2.js']
    },
    custom: {
      'dest/custom-output.js': ['src/custominput1.js', 'src/custominput2.js']
    }

 }

If production could even have the destination name to custom-output.min.js that would be even more ideal.

Tried an if-else statement but inside the grunt task definition that doesn't fly.

Upvotes: 1

Views: 364

Answers (2)

Mike Mellor
Mike Mellor

Reputation: 1346

As the grunt config is just json you could use grunt templates and have your files as a property of the config.

uglifyFiles: {

  vendor: {
    // this name should change based on the environment
    'dest/vendor-output.js': ['src/vendor-input1.js', 'src/vendor-input2.js']
  },
  custom: {
    'dest/custom-output.js': ['src/custominput1.js', 'src/custominput2.js']
  }
},
uglify: {

  production: {
    options: {
      compress: true
    },
    files: '<%= uglifyFiles %>'
  },

  development: {
    options: {
      compress: false,
      beautify: true
    },
    files: '<%= uglifyFiles %>'
  }
}

http://gruntjs.com/configuring-tasks#templates

Sorry i didn't quite understand this question

If production could even have the destination name to custom-output.min.js that would be even more ideal.

Could you give a little more info, or is the above what you where trying to achieve?

EDIT

Seems like what you're trying to do takes the repeat part out of DRY as you actually want slightly different code in each. It could be done but not in the json, you'd need to use js and use bracket notation to create the destination as its a key. I think a much simpler way, and what grunt is set up like this for, would be to do the following.

vendorUglifyFiles: ['src/vendor-input1.js', 'src/vendor-input2.js'],
customUglifyFiles: ['src/custominput1.js', 'src/custominput2.js'],
uglify: {

  production: {
    options: {
      compress: true
    },
    files: {
      vendor: {
        'dest/vendor.min.js': '<%= vendorUglifyFiles %>'
      },
      custom: {
        'dest/custom.min.js': '<%= customUglifyFiles %>'
      }
    }
  },

  development: {
    options: {
      compress: false,
      beautify: true
    },
    files: {
      vendor: {
        'dest/vendor.js': '<%= vendorUglifyFiles %>'
      },
      custom: {
        'dest/custom.js': '<%= customUglifyFiles %>'
      }
    }
  }
}

Edit: 11-08-2016, 15:12

Removed the level that throws the indexOf error:

vendorUglifyFiles: ['src/vendor-input1.js', 'src/vendor-input2.js'],
customUglifyFiles: ['src/custominput1.js', 'src/custominput2.js'],
uglify: {

  production: {
    options: {
      compress: true
    },
    files: {
      'dest/vendor.min.js': '<%= vendorUglifyFiles %>',
      'dest/custom.min.js': '<%= customUglifyFiles %>'
    }
  },

  development: {
    options: {
      compress: false,
      beautify: true
    },
    files: {
        'dest/vendor.js': '<%= vendorUglifyFiles %>',
        'dest/custom.js': '<%= customUglifyFiles %>'
    }
  }
}

That does the trick.

Upvotes: 1

Bob van Luijt
Bob van Luijt

Reputation: 7588

Grunt is Javascript, so you can actually add IF/ELSE statements.

Example:

files: {
    (() => { 
        if (grunt.option('vendor')) {
            return {
                'dest/vendor-output.js': ['src/vendor-input1.js', 'src/vendor-input2.js']
            }
        } else (grunt.option('release')) {
            return {
                'dest/custom-output.js': ['src/custominput1.js', 'src/custominput2.js']
            }
        }
    }())
}

/***
 * OR SOMETHING LIKE
 **/

files: {
    (() => { 
        switch(grunt.option) {
            case 'vendor':
                return {
                    'dest/vendor-output.js': ['src/vendor-input1.js', 'src/vendor-input2.js']
                };
                break;
            case 'release:
                return {
                    'dest/custom-output.js': ['src/custominput1.js', 'src/custominput2.js']
                };
                break;
            default:
                return {};
        }
    }
}

Obviously, you need to change this to your desired situation because it is now unknow how you address vendor and/or release.

Upvotes: 0

Related Questions