简体   繁体   中英

Use Grunt newer with custom task

I'm trying to use grunt-newer to watch files from a folder and if any is changed, trigger a custom task.

I have something like this in my Gruntfile.js:

grunt.initConfig({
   watch: {
      widgets: {
         files: "/somepath/*.js",
         tasks: ['newer:mycustomtask']
      }
   }
});

grunt.registerTask("mycustomtask", ["description of my task"], function() {
  console.log("me has been triggered");
});

Whenever I run "grunt watch", I have this output:

Running "watch" task
Waiting...
File "/somepath/WidgetA.js" changed.
Running "newer:mycustomtask" (newer) task
Fatal error: The "newer" prefix is not supported for aliases

I googled but didn't found anything about this. Anyone knows how could I implement this? I need to now in my "customtask" which files have been changed

If you reference a task (inside watch or concurrent eg) which is either not installed or not configured you get this error output.

This happens often when you copy-paste a watch config from a different project.

I came across a similar requirement and the solution I ended up with is roughly as follows. Let's assume that the project structure is:

Gruntfile.js
package.json
src/
    config.js
    data.js
tasks/
    customtask.js

Here, the src directory contains data which will be monitored by watch , while the definition of the custom task is stored in tasks/customtask.js . For the purpose of this example, this task will only print the file names of the changed files:

var fs = require('fs');
var path = require('path');

module.exports = function(grunt) {
    grunt.registerMultiTask('customtask', function() {
        var done = this.async();

        if(!this.files){ done(); return; }

        this.files[0].src.forEach(file_name => {
            console.log(file_name);
        });

        done();
    });
};

Now, Gruntfile.js looks like:

module.exports = function(grunt) {

    const files = ['src/config.js', 'src/data.js'];

    grunt.initConfig({

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

        customtask: {
            release: {
                src: files
            }
        },

        watch: {
            data: {
                files: files,
                tasks: ['customtask:release']
            },
            options: {
                spawn: false
            }
        }

    });

    grunt.loadTasks('tasks');
    grunt.loadNpmTasks('grunt-contrib-watch');

    var changedFiles = Object.create(null);
    var onChange = grunt.util._.debounce(function() {
        grunt.config('customtask.release.src', Object.keys(changedFiles));
        changedFiles = Object.create(null);
    }, 200);
    grunt.event.on('watch', function(action, filepath) {
        changedFiles[filepath] = action;
        onChange();
    });

    grunt.registerTask('build', ['watch:data']);
};

here, it specifies that:

  1. the files of interest are ['src/config.js', 'src/data.js']
  2. that our customtask operates in principle on these files (in case it would be invoked directly)
  3. that watch is supposed to observe these files and launch customtask:release whenever something changes
  4. grunt.loadTasks('tasks') loads all "tasks definitions" from the directory tasks , ie, here only the customtask
  5. grunt.registerTask('build', ['watch:data']) defines a "shortcut" for watch:data

Finally, in order to invoke customtask only for the changed files, this example uses the strategy employed in the documentation in the section "Compiling files as needed". In loose terms, it assembles all changed files in an object the keys of which are then used to modify the src property of the customtask on-the-fly.

Running grunt build then initiates the "watch". If one runs in another terminal window for example touch src/*.js , the output is:

Running "watch:data" (watch) task
Waiting...
>> File "src/config.js" changed.
>> File "src/data.js" changed.

Running "customtask:release" (customtask) task
src/config.js
src/data.js

where the last two lines come from customtask ...

You just need to have a config entry (even an empty one) for your task:

grunt.initConfig({

  mycustomtask: {
  },

  watch: {
    widgets: {
      files: "/somepath/*.js",
      tasks: ['newer:mycustomtask']
    }
  }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM