grunt icon indicating copy to clipboard operation
grunt copied to clipboard

grunt.config.get() removes methods from ES6 classes

Open IgorAufricht opened this issue 8 years ago • 4 comments

The grunt.config.get() removes methods from ES6 classes (it works correctly when using prototypes).

  • The problem does not occur when using grunt.config.getRaw() instead of grunt.config.get().
  • An example usecase is using internal webpack >= 2 plugins (e.g. IgnorePlugin), which are indeed written in ES6.

To reproduce:

  1. create a new Gruntfile.js with the following contents:
module.exports = function(grunt) {
  function TestPrototype () {}
  TestPrototype.prototype.func = function () {
    console.log('Prototype method was called.');
  }

  class TestES6 {
    func() {
      console.log('ES6 method was called.');
    }
  }
  
  grunt.initConfig({
    test: {
      testPrototype: new TestPrototype(),
      testES6: new TestES6()
    }
  });
  
  grunt.config.get('test').testPrototype.func();
  grunt.config.get('test').testES6.func();
};
  1. run grunt --help

Expected output:

$ grunt --help
Prototype method was called.
ES6 method was called.
Grunt: The JavaScript Task Runner (v1.0.1)

(... the rest of grunt --help output ...)

Actual output:

$ grunt --help
Prototype method was called.
Loading "Gruntfile.js" tasks...ERROR
>> TypeError: grunt.config.get(...).testES6.func is not a function
Grunt: The JavaScript Task Runner (v1.0.1)

(... the rest of grunt --help output ...)

Environment: node v6.3.0 grunt v1.0.1

IgorAufricht avatar Jul 07 '17 10:07 IgorAufricht

Running into same issue with webpack 4 plugins.

Changing to getRaw from get in config.js looks like it fixes the issue.

// Get/set config data. If value was passed, set. Otherwise, get.
var config = module.exports = function(prop, value) {
  if (arguments.length === 2) {
    // Two arguments were passed, set the property's value.
    return config.set(prop, value);
  } else {
    // Get the property's value (or the entire data object).
    return config.get(prop);
  }
};

ruaneg avatar Apr 10 '18 08:04 ruaneg

Im testing out the fix on my fork atm. If it works OK and I get no objections Ill open up a pull request with the change on the main repo here.

ruaneg avatar Apr 10 '18 13:04 ruaneg

Making that change would result in a lot of broken Gruntfiles. Currently Gruntfiles rely on the config being automatically processed by grunt.template.process() which grunt.config.get does vs grunt.config.getRaw.

The reason prototypes work and es6 classes do not, is because methods on es6 classes are not enumerable. So in order to fix, one would need to change the template processing to handle non-enumerable properties on an object.

shama avatar Apr 24 '18 05:04 shama

Is there any plan to support es6 classes in future?

ruaneg avatar Jun 20 '18 09:06 ruaneg