Domanda

I'm using grunt-contrib-less and grunt-contrib-watch together. My less task uses the files array format to define multiple src and dest's. I'd like to reference those same files from the watch task. Like this:

grunt.initConfig({
  less: {
    build: {
      files: [
        {src: 'src/aa.less', dest: 'dest/a.css'},
        {src: 'src/aa1.less', dest: 'dest/a1.css'}
      ]
    }
  },
  watch: {
    less: {
      files: '<%= less.build.files %>',
      tasks: ['less']
    }
  }
});

That underscore template works, but watch can't process the files array format, it only accepts file input as a string or array of strings. Here's what I've tried:

  • '<%= less.build.files.src %>' doesn't work because less.build.files is an array, not an object.

  • '<%= _(less.build.files).pluck("src").value() %>' doesn't work, because even though it makes the right file list, it resolves to single string 'src/aa.less,src/aa1.less', not an array.

  • '{<%= _(less.build.files).pluck("src") %>}' does work, as suggested here https://stackoverflow.com/a/21608021/490592, but it doesn't feel right. I'm trying to target a specific set of files, not pattern match from my whole project directory.

  • grunt.config.set('watch.less.files', _(grunt.config.get('less.build.files')).pluck('src').value()); works, but this must be separate from the initConfig.

Is there a more elegant way to accomplish this?

È stato utile?

Soluzione 2

I don't understand why you haven't simply refactored the files section into a variable? The following achieves your goal of "like to reference those same files from the watch task."

var yourFiles = [
    {src: 'src/aa.less', dest: 'dest/a.css'},
    {src: 'src/aa1.less', dest: 'dest/a1.css'}
];

grunt.initConfig({
    less: {
        build: {
            files: yourFiles 
        }
    },
    watch: {
        less: {
            files: yourFiles 
            tasks: ['less']
        }
    }
});

P.S. You might enjoy reading up on this to know what happens under the hood when referencing variables in the templates, for some more advanced hacking later on.

Altri suggerimenti

I confirmed that grunt-contrib-watch does not support the files array format. I settled on using the grunt-config-set technique I mentioned above.

Even though watch doesn't support the files array format, I make sure my custom tasks are compatible with it so I don't have to use the workarounds from my question. I've attached an example. For read-only tasks, I add a useDest option, so they can be configured to operate on dest's instead of src's. This helps when you want to "pipe" one task into another task.

module.exports = function (grunt) {

  grunt.registerMultiTask('example', 'Example read-only task', function () {
    var options = this.options({
          useDest: false, // When true, operate on dest files, instead of src
        });
        files = this.files.map(function (file) {
          return { src: (options.useDest) ? [file.dest] : file.src }
        });
    files.forEach(function (file) {
      grunt.log.writeln('Source: ' + grunt.log.wordlist(file.src));
    });
  });

  grunt.loadNpmTasks('grunt-contrib-concat');

  grunt.initConfig({
    concat: {
      build: {
        files: [
          { src: 'node_modules/grunt/lib/grunt/*.js', dest: 'lib.js' },
          { src: 'node_modules/grunt/internal-tasks/*.js', dest: 'tasks.js' }
        ]
      }
    },
    example: {
      build: {
        options: {
          useDest: true
        },
        files: '<%= concat.build.files %>'
      }
    }
  });

};

The task will output:

Running "example:build" (example) task
Source: lib.js
Source: tasks.js
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top