在“管道"之间传递变量在吞咽
我正在尝试编写一个 gulp 任务,该任务通过 gulp-prompt 插件获取一些用户输入.但我无法将该输入传递给其他例如:
I'm trying to write a gulp tasks that takes some user input via the gulp-prompt plugin. But I'm having trouble passing that input along to other eg:
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
.
Assuming I enter hello
at the prompt, I was expecting the confirmation to say You said Hello
, but it says You said MONKEY
.
Gulp 可以做到这一点吗?
Is this possible with Gulp?
推荐答案
这里的问题是你正在创建第二个提示 ('You said ' + myVar
) before 第一个提示已执行:
The issue here is that you are creating the second prompt ('You said ' + myVar
) before the first prompt has been executed:
- 将
myVar
设置为'MONKEY'
- 创建信息流
- Set
myVar
to'MONKEY'
- Create streams
- 创建
src
流,这是异步的 - 创建第一个提示,并将其添加到 src 流中
- 使用
myVar
的当前值创建第二个提示,并将其添加到第一个提示流中
- Create
src
stream, which is asynchronous - Create first prompt, and add it to the src stream
- Create second prompt using current value of
myVar
, and add it to the first prompt stream
- 加载源
- 运行第一个提示,设置
myVar
- 使用之前生成的消息运行第二个提示
<小时>
如果您想将其全部保留为单个流,唯一的解决方案是在允许闭包(函数)的东西中使用变量.一些插件已经接受闭包作为参数,但大多数不接受.
The only solution if you want to keep it all as a single stream is to use the variable within something that allows for a closure (function). Some plugins already accept a closure as an argument, but most don't.
将流包装在闭包中的一种解决方案是 gulp-tap,它不是专门为这种情况设计的,但应该可以工作.它看起来像这样:
One solution to wrap a stream in a closure that would work here is gulp-tap, which isn't designed for this scenario specifically, but should work. it looks like this:
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]);
});
});
因为它被包装在一个闭包中,并且针对每个文件进行评估,所以它将获取变量的 current 值.但是,因为它适用于每个文件,所以您会看到处理 每个 文件的提示一次.
Because this is wrapped in a closure, and evaluated for each file, it will pick up the current value for the variable. However, because it works on each file, you'll see the prompt once for each file processed.
更好的解决方案是将您的任务分成多个相互依赖的任务.看起来像这样:
An better solution would be to separate your task into multiple, dependent tasks. That would look something like this:
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
),所以变量将是设置正确.
Now the first task (userinput1
) will run and complete before the second one is processed (userinput2
), so the variable will be set correctly.
注意:确保从您的任务中return
流,否则它们会被同步处理,并且您的变量不会被设置.
NOTE: Make sure you
return
the stream from your tasks, otherwise they are processed synchronously, and your variable won't get set.
<小时>
最后,完全放弃 gulp-prompt
任务可能更有意义,因为它与流没有太大关系.您最好在任务中直接使用 Node JavaScript 来收集用户的输入(最好以同步方式),然后在 gulp-stream 中处理您的文件.
Finally, it might make more sense to forgo the gulp-prompt
task altogether, because it doesn't really have much to do with the stream. You'd probably be better off using straight Node JavaScript within your task to gather the user's input (preferably in a synchronous manner), then processing your files in a gulp-stream after that.
相关文章