How to pass a parameter to gulp-watch invoked task

2019-04-08 12:05发布

问题:

I am trying to pass a parameter to a task that is being invoked by gulp-watch. I need it because I am trying to build a modular framework.

  • So if a file changes in module 1, the other modules don't need to be rebuild.
  • And I want just one function to create the concatted & uglified files per module.

This is what I got so far:

//here I need the 'module' parameter
gulp.task('script', function(module) { ... }

gulp.task('watch', function() {
    gulp.watch('files/in/module1/*.js', ['script']); //here I want to pass module1
    gulp.watch('files/in/module2/*.js', ['script']); //here I want to pass module2
});

A lot of the documentation/examples seems to be outdated (gulp.run(), gulp.start()).

I hope someone can help me out here.

回答1:

I had the very same issue, searched for a while, and the "cleanest" way I came up with, uses the .on() event handler of gulp.watch(), and the .env property of gulp-util:

var gulp = require('gulp');
$.util = require('gulp-util');

var modules = {
    module1: {}, // awesome module1
    module2: {}  // awesome module2
};

gulp.task('script', function(){
    var moduleName = $.util.env.module;
    // Exit if the value is missing...
    var module = modules[moduleName];
    if (!module) {
        $.util.log($.util.colors.red('Error'), "Wrong module value!");
        return;
    }
    $.util.log("Executing task on module '" + moduleName + "'");
    // Do your task on "module" here.
});


gulp.task('watch', function () {
    gulp.watch(['files/in/module1/*.js'], ['script']).on('change', function () {
        $.util.env.module = 'module1';
    });
    gulp.watch(['files/in/module2/*.js'], ['script']).on('change', function () {
        $.util.env.module = 'module2';
    });
});

gulp-util also comes in handy if you need to pass (global) parameters from the shell:

 [emiliano@dev ~]# gulp script --module=module1 --minify

Hope this helps someone else out there!

Regards.



回答2:

In that i will answer directly the question "How to pass a parameter to gulp-watch invoked task"

My way of doing, and one of the possibility i see, is to use a global variable to pass the value between the two blocks. you set it just before launching the task in the watcher. And in the task, just at the start you pass it to a local variable.

See this answer for more details: https://stackoverflow.com/a/49733123/7668448

In what you want to achieve, you can too use just one watcher over the directory that hold all modules. If so is the structure. Then when a change happen, you can recover the changed file path. From that you can deduce what module does belong to. By getting the Module folder. That way you will not need to add a new watcher for each new module. Which can be nice when there is multiple contributors to the project for example when working on open source. And you do it one time, and don't have to care about adding anything. Just like with the delegation principle, with DOM event handling when there is multiple elements. Even if the chosen structure, doesn't have all the modules in one directory. You can stay pass multiple globs to the one watcher.

gulp.watch(['glob1/**/*.js', 'glob2/**/*.js',...], function(evt) {/*.....*/});

And following the structure you have, you can work your way to deduce what module is.

For the watcher here how i suggest you do it:

  watch('./your/allModulesFolder/**/*.js', function (evt) {
    rebuildModulWatchEvt = evt; //here you update the global var
    gulp.start('rebuildModul'); // you start the task
})

The evt here hold multiple info: cwd, base, state, _contents ...etc And what interest us is path. So evt.path will give you the path of the changed file.

In your task either you do that:

gulp.task('rebuildModul', function() {
     let evt = rebuildModulWatchEvt; // at all start you pass it to a local var
     let filePath = evt.path; // how you get the changed file path
     // your code go here for the rest, following your structure, get the path for the module folder
});

or you use a function :

gulp.task('rebuildModul', function() {
     rebuildModulTaskRun(rebuildModulWatchEvt);
});
function rebuilModulTaskRun(evt) {
      let filePath = evt.path;
      // your code go here for the rest, following your structure, get the path for the module folder
}