在Gulp中的"管道"之间传递变量

gar*_*uan 11 javascript gulp

我正在尝试编写一个gulp任务,通过gulp-prompt插件获取一些用户输入.但我无法将输入传递给其他人,例如:

gulp.task('userinput', function(){

    var myVar = 'MONKEY';

    gulp.src('./templates/_component.*')
    .pipe(prompt.prompt([
        {
            type: 'input',
            name: 'userInput',
            message: 'Say something'
        }
    ], function(res){
        myVar = res.userInput;
    }))
    .pipe(prompt.confirm('You said ' + myVar));
});
Run Code Online (Sandbox Code Playgroud)

假设我hello在提示时输入,我希望确认说You said Hello,但它说You said MONKEY.

这可能与Gulp有关吗?

Ove*_*ous 18

这里的问题是你第一个提示执行之前创建第二个prompt('You said ' + myVar):

  1. 设置myVar'MONKEY'
  2. 创建流
    1. 创建src流,这是异步的
    2. 创建第一个提示,并将其添加到src流
    3. 使用当前值创建第二个提示myVar,并将其添加到第一个提示流
  3. 直到现在才对流进行处理
    1. 加载源
    2. 运行第一个提示,设置 myVar
    3. 使用以前生成的消息运行第二个提示

如果要将所有内容保存为单个流,唯一的解决方案是在允许闭包(函数)的内容中使用该变量.一些插件已经接受了一个闭包作为参数,但大多数插件都没有.

将流包装在一个可以在这里工作的闭包的一个解决方案是gulp-tap,它不是专门针对这种情况设计的,但是应该可行.它看起来像这样:

var tap = require('gulp-tap');

//...

gulp.task('userinput', function(){

    var myVar = 'MONKEY';

    gulp.src('./templates/_component.*')
    .pipe(prompt.prompt([
        {
            type: 'input',
            name: 'userInput',
            message: 'Say something'
        }
    ], function(res){
        myVar = res.userInput;
    }))
    .pipe(tap(function(file, t) {
        // format is t.through(stream-function, [arguments...])
        return t.through(prompt.confirm, ['You said ' + myVar]);
    });
});
Run Code Online (Sandbox Code Playgroud)

因为它包含在一个闭包中,并为每个文件进行评估,所以它将获取该变量的当前值. 然而,因为它的工作原理上的每个文件,你会看到提示后每个处理的文件.


更好的解决方案是将您的任务分成多个相关任务.这看起来像这样:

var myVar = 'MONKEY';

gulp.task('userinput1', function(){

    return gulp.src('./templates/_component.*', {read: false})
        .pipe(prompt.prompt([
            {
                type: 'input',
                name: 'userInput',
                message: 'Say something'
            }
        ], function(res){
            myVar = res.userInput;
        }));
});

gulp.task('userinput', ['userinput1'], function() {
    return gulp.src('./templates/_component.*')
        .pipe(prompt.confirm('You said ' + myVar));
});
Run Code Online (Sandbox Code Playgroud)

现在第一个task(userinput1)将在第二个task()处理之前运行并完成userinput2,因此变量将被正确设置.

注意:确保您return的任务流,否则它们将被同步处理,您的变量将不会被设置.


最后,gulp-prompt完全放弃任务可能更有意义,因为它与流没有多大关系.您可能最好在任务中使用直接的Node JavaScript来收集用户的输入(最好以同步方式),然后在gulp-stream中处理文件.