2014-01-23 60 views
3

我有兩個javascript和css文件,我使用gulp-rev lib [1]的分叉回購,它們都重命名文件並更新html文件中的文件引用。Gulp有兩個任務相互衝突

不幸的是,這兩個任務之間存在爭用條件,導致樣式表引用以md5命名的文件或者js文件勝出。

我試圖使用承諾以及回調(見下文),以允許任務的同步,但從來沒有對css和js md5引用做出。

sindresorhus的lib只重命名文件,並沒有修復鏈接,那麼有沒有更好的方法來修復html鏈接,或者是使用分叉插件他們的方式去(有一些我缺少的修復)?

gulp.task('rev', ['rev-js']); 
gulp.task('rev-js', ['rev-css'], function(cb) { 
    var context = rev.Context(); 
    gulp.src(['./build/public/js/woddy.js', './build/public/js/angular.js', './build/public/js/components.js']) 
    .pipe(rev(context)) 
    .pipe(gulp.dest('./build/public/js')); 
    gulp.src('./build/public/app.html') 
    .pipe(context.replace(/src="js\/(\w+\.js)"/g, 'src="js/{{$1}}"')) 
    .pipe(gulp.dest('./build/public')); 
}); 
gulp.task('rev-css', function() { 
    var context = rev.Context(); 
    gulp.src('./build/public/styles/woddy.css') 
    .pipe(rev(context)) 
    .pipe(gulp.dest('./build/public/styles')); 
    gulp.src('./build/public/app.html') 
    .pipe(context.replace(/href="styles\/(\w+\.css)"/g, 'href="styles/{{$1}}"')) 
    .pipe(gulp.dest('./build/public')); 
}); 
  1. https://github.com/dtinth/gulp-rev
+0

另請參閱有關以系列方式運行任務的文檔:https://github.com/gulpjs/gulp/blob/master/docs/recipes/running-tasks-in-series.md – nha

回答

5

差不多大口內的所有操作都是異步的,這意味着你需要使用3 supported methods for notifying when a task is complete之一。 (如果一個任務確實是同步的,你不需要做任何事情。)

  1. 返回流從一個方法(通常是最容易)
  2. 返回一個承諾(在一飲而盡罕見)
  3. 使用提供給任務函數的回調方法。

首先,您的rev-js方法中有回調參數。通過包含變量(cb),但從不使用它,該任務將從永不「完成」,因此rev將等待它。其次,你在每個任務中都有兩組流,它們是同時運行的,而不是像你想象的那樣一個接一個地運行一組。例如,在rev-js中,啓動了js任務,然後啓動html任務,然後可以按任意順序處理和完成。很可能,HTML任務將在所有JS文件處理完成之前完成。

就我個人而言,我將拆分HTML任務並使用其中一個現有插件(例如gulp-inject,這很容易),然後分別處理。

所以,這種情況下,你的文件應該是這樣的

gulp.task('rev', ['rev-html']); 

gulp.task('rev-html', ['rev-js', 'rev-css'], function() { 
    // change to reference specific JS and CSS files as necessary 
    return gulp.src(['./build/public/**/*.*', '!./build/public/index.html']) 
    .pipe(inject('index.html')) 
    .pipe(gulp.dest('./build/public')); 
}); 

gulp.task('rev-js', function() { // NOTE: no `cb` here 
    var context = rev.Context(); 
    return gulp.src(['./build/public/js/woddy.js', './build/public/js/angular.js', './build/public/js/components.js']) 
    .pipe(rev(context)) 
    .pipe(gulp.dest('./build/public/js')); 
}); 
gulp.task('rev-css', function() { 
    var context = rev.Context(); 
    return gulp.src('./build/public/styles/woddy.css') 
    .pipe(rev(context)) 
    .pipe(gulp.dest('./build/public/styles')); 
}); 

現在,如果你真的想手動處理的注入,那麼你應該使用一個stream combiner並返回結果的流。但是你仍然需要在HTML步驟之前完成JS步驟。

+0

感謝您的幫助(再次:)。沒有調用回調可能是由於一些撤銷(有很多),但我沒有辦法,因爲我只是在調用異步方法後調用它,這是因爲事情仍然是異步的。我使用了時間戳,因爲這是繞過異步問題的東西,但也導致人們總是不得不下載不變的角度文件。有一件事對我來說還不清楚,就是天氣連鎖的任務(['rev-js''rev-css'))也是彼此異步運行的。你能澄清這個嗎? – chris

+0

任務依賴關係同時運行。你應該繼續努力讓它工作 - 'rev'插件對我來說非常有用。 – OverZealous

+0

我一定會用你的建議。如果你使用rev插件,你是如何做到的?上面的例子使用提供上下文的rev插件的fork,那麼使用sindresorhus的版本還有另一種方法嗎? – chris