2014-12-02 15 views
18

我試圖有條件地基於變量的值來管理文件流,以此來定義兩個獨立的構建環境(即開發和生產)。在運行依賴關係之前,是否可以在吞食任務中分配一個變量?

有些任務可以單獨使用命令行標誌,像這樣運行: gulp scripts --env production

然後會做一些生產專用管道的步驟:

gulp.task('scripts', function() { 
    var jsFilter = filter(['*.js']), 
    appFiles; 

    return gulp.src(appFiles) 
    .pipe(jsFilter) 
    .pipe(concat('application-build.js')) 
    .pipe(gulpif(env === 'production', uglify())) 
    .pipe(size()) 
    .pipe(gulpif(env === 'production', gulp.dest('dist/js'), gulp.dest('tmp/js'))) 
    .pipe(browserSync.reload({ stream: true })); 
}); 

我有一個build任務調用許多其他任務作爲依賴項(例如,包括這個scripts任務)。我希望這個build任務在之前分配一個變量(env,在這種情況下)運行任務依賴關係。這意味着:

gulp.task('build', ['scripts', 'styles', 'otherstuff'], function() { 
    env = 'production'; 
} 

不起作用,因爲依賴關係在任務主體之前運行。

我現在有它gulp.start實現:

gulp.task('build', function() { 
    env = 'production'; 
    gulp.start('scripts'); 
}); 

But the .start method isn't actually part of gulp's public API - 它comes from Orchestrator - 並且不打算使用任何東西。另外,等效方法gulp.run從前不久被棄用。

所以我想知道 - 有沒有另一種方式,我可以在運行其依賴關係之前分配任務中的變量?

(或者,也許有對實施一口類似構建環境更好的辦法?)

回答

13

你可以創建一個特定的任務來設置環境和之前你的其他任務運行。

gulp.task('set-production', function() { 
    env = 'production'; 
}); 

// Doesn't quite work because tasks are run in parallel 
gulp.task('build', ['set-production', 'scripts', 'styles', 'otherstuff']); 

這裏的問題是,你的任務將並行運行,這意味着set-production任務後,可以在其他任務運行。你可以用run-sequence包來解決這個問題。

var runSequence = require('run-sequence'); 
gulp.task('build', function(callback) { 
    runSequence('set-production', ['scripts', 'styles', 'otherstuff'], callback); 
}); 

這將首先運行set-production任務,然後並行運行scriptsstylesotherstuff任務。

+0

謝謝!我喜歡這種方法好得多。快速的問題 - (我知道這是用在'run-sequence'的文檔中,但爲什麼最後會有回調? – wisew 2014-12-02 19:33:07

+0

由於吞吐任務是異步的,回調讓吞噬知道任務完成。如果任務被聲明爲另一個任務的依賴關係,那麼這是必需的。 – 2014-12-02 21:12:47

+0

我們是否需要'set-production'任務,我們不能直接在運行序列之前設置env變量嗎? – 2016-03-10 16:36:29

15

正確的方法

我不同意@Justin。用任務定義一個環境變量是一個想法的黑客。這樣做更好用gutil.env這樣做。

gulp --env prod task 

gulp.task('myTask',() => { console.log(gutil.env.env) }) 

現在從這一點,你有gulp.env.env設置。

或者,您也可以像this example in this ticket..那樣從Gulp的開發者那裏得到這個解決方案,它首先建議使用環境變量,但提供這個習慣用法。

function js(shouldMinify) { 
    return gulp.src('./js/*.js') 
     .pipe(concat('app.js')) 
     .pipe(gulpif(shouldMinify, uglify())) 
     .pipe(gulp.dest('js')); 
}); 

gulp.task('develop', function() { 
    shouldMinify = false; 
    return js(shouldMinify); 
}); 

gulp.task('build', function() { 
    shouldMinify = true; 
    return js(shouldMinify); 
}); 

same developer (phated)總是說,使用ENV ...

更何況,你應該控制這種類型的邏輯與環境變量或命令行標誌。 - phated

據推測,他指的是使用gutil.noop()gulp-util的文檔:

// gulp should be called like this : 
// $ gulp --type production 
gulp.task('scripts', function() { 
    gulp.src('src/**/*.js') 
    .pipe(concat('script.js')) 
    // LOOK BELOW: if we don't send to uglify, we push to noop stream. 
    .pipe(gutil.env.type === 'production' ? uglify() : gutil.noop()) 
    .pipe(gulp.dest('dist/')); 
}); 
+2

這比我的答案要好。獲得我的讚賞。然而,你的例子很混亂,因爲'js'函數中的參數'shouldMinify'覆蓋了全局變量'shouldMinify',並且全局變量從不使用。你能否更新你的例子來刪除全局'shouldMinify'? – 2016-02-11 18:41:50

+0

@JustinHoward很好抓,刪除。我從git上的票上覆制粘貼。 – 2016-02-11 19:55:02

相關問題