2014-01-23 2 views
3

У меня есть как javascript, так и css-файлы, которые я использую разветвленное репо gulp-rev lib [1], которое переименовывает файлы и обновляет ссылки на файлы в html-файле.У Gulp есть две задачи, конфликтующие друг с другом

К сожалению, между этими двумя задачами существует условие гонки, в результате чего либо ссылка на таблицу стилей будет указана в файле с именем md5, либо в результате удаляются файлы js.

Я попытался использовать обещания, а также обратные вызовы (см. Ниже), чтобы обеспечить синхронизацию задач, но никогда не используются оба ссылки css и js md5.

sindresorhus's 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 и возвращает результат этого потока. Но вам еще нужно сделать шаг JS до шага HTML.

+0

Спасибо за помощь (снова :). Не вызывать обратный вызов, вероятно, было связано с некоторыми отменами (их было много), но я был в отъезде, так как я просто вызывал его после вызова методов async, что было тогда причиной того, что все еще было асинхронным.Я прибегал к использованию временных меток, поскольку это было чем-то, что обошло проблемы асинхронности, но это также приводит к тому, что людям всегда приходится скачивать неизменные угловые файлы. Одна вещь, которая до сих пор остается неясной для меня, - это погоня за целыми задачами ([rev-js '' rev-css]) также запускаются async друг к другу. Не могли бы вы прояснить это? – chris

+0

Зависимости задач запускаются одновременно. Вы должны продолжать пытаться заставить его работать - плагин 'rev' отлично работает для меня. – OverZealous

+0

Я обязательно буду использовать то, что вы предложили. Если вы используете плагин rev, как вы это делаете? В приведенном выше примере используется вилка плагина rev, которая предоставляет контекст, так есть ли другой способ использования версии sindresorhus? – chris

Смежные вопросы