在“管道”之间传递变量在Gulp [英] Passing variables between "pipes" in 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));
});
假设我在提示符处输入 hello
我期待确认说你说你好
,但它说你说MONKEY
。
这与Gulp可能吗?
这里的问题是您正在创建第二个提示符('您说'+ myVar
)在执行第一个提示之前:
- 设置
myVar
至'MONKEY'
- 创建流
- 创建
src
流,它是异步的 - 创建第一个提示,并将其添加到src流
- 使用当前值
myVar
创建第二个提示,并将其添加到第一个提示流
- 创建
-
-
-
- 加载源
- >运行第一个提示,设置
myVar
- 使用先前生成的消息运行第二个提示 ol>
唯一的解决方案是如果您想将它全部保存为单个流是在允许clo的东西内使用变量肯定(功能)。一些插件已经接受了一个闭包作为参数,但大部分都不会。
将一个流封装在闭包中的一个解决方案是 gulp-tap ,它不是专门为这种情况设计的,但应该可以工作。它看起来像这样:
var tap = require('gulp-tap');
gulp.task('userinput',function(){
var myVar ='MONKEY';
$ b $ gulp.src('./ templates / _component。*')
.pipe(prompt.prompt([
{
type:'input',
名称:'userInput',
message:'说一些'
}
],函数(res){
myVar = res.userInput;
}))
.pipe(tap(函数(file,t){
//格式为t.through(stream-function,[arguments ...])
返回t.through(提示。确认,['您说'+ myVar]);
});
});
因为它封装在一个闭包中,并对每个文件进行评估,所以它会为变量提取 current 值。但是,因为它适用于每个文件,所以每次处理每个文件都会看到提示。
$ b
更好解决办法是将你的任务分成m个这样看起来像这样:
var myVar ='MONKEY';
$ b gulp.task('userinput1',function(){
return gulp.src('./ templates / _component。*',{read:false})
.pipe(prompt.prompt([
{
type:'input',
name:'userInput',
message:'说点什么'
}
],function(res){
myVar = res.userInput;
}));
});
gulp.task('userinput',['userinput1'],function(){
return gulp.src('./ templates / _component。*')
。 (prompt.confirm('你说'+ myVar));
});
现在第一个任务( userinput1
)将运行并完成之前处理第二个( userinput2
),因此该变量将被正确设置。
注意:确保您
返回
来自任务的流,否则它们将被同步处理,你的变量不会被设置。
最后,感觉完全放弃了 gulp-prompt
任务,因为它并不真正与流有很大关系。你可能会更好的在你的任务中使用直接的Node JavaScript来收集用户的输入(最好是以同步的方式),然后在你的文件中处理你的文件。
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));
});
Assuming I enter hello
at the prompt, I was expecting the confirmation to say You said Hello
, but it says You said MONKEY
.
Is this possible with Gulp?
The issue here is that you are creating the second prompt ('You said ' + myVar
) before the first prompt has been executed:
- Set
myVar
to'MONKEY'
- Create streams
- 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
- Create
- Only now are the streams executed processed
- Load sources
- Run first prompt, set the
myVar
- Run the second prompt using previously generated message
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.
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]);
});
});
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));
});
Now the first task (userinput1
) will run and complete before the second one is processed (userinput2
), so the variable will be set correctly.
NOTE: Make sure you
return
the stream from your tasks, otherwise they are processed synchronously, and your variable won't get set.
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.
这篇关于在“管道”之间传递变量在Gulp的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!