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

时间:2014-02-25 21:17:15

标签: javascript gulp

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

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));
});

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

Gulp有可能吗?

1 个答案:

答案 0 :(得分:18)

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

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

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

    将流包装在一个可在此处工作的闭包中的一个解决方案是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]);
        });
    });
    

    因为它包含在一个闭包中,并针对每个文件进行评估,所以它将获取该变量的当前值。 但是,因为它适用于每个文件,所以您会看到每个文件处理过一次提示。


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

    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));
    });
    

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

      

    注意:请确保return来自您的任务的流,否则它们会被同步处理,并且您的变量将无法设置。


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