Как насчет этой комбинации gulp -concat и lazypipe вызывает ошибку при использовании gulp 4?
Я обновляюсь от Gulp от 3 до 4, и у меня возникает ошибка:
The following tasks did not complete: build
Did you forget to signal async completion?
Я понимаю, что он говорит, но не может понять, почему этот код запускает его.
Ошибка или нет, задача завершена (файлы объединены и записаны в dest). Выполнение одного и того же кода без lazypipe не приводит к ошибке, и удаление конкатенации внутри lazypipe также устраняет ошибку.
Обертка всей вещи в том, что создает поток (например, поток слияния), устраняет проблему. Я предполагаю, что что-то о взаимодействии между gulp -concat и lazypipe препятствует правильному возврату потока.
Здесь (упрощенная) задача:
gulp.task('build', function() {
var dest = 'build';
var buildFiles = lazypipe()
.pipe(plugins.concat, 'cat.js') // Task will complete if I remove this
.pipe(gulp.dest, dest);
// This works
// return gulp.src(src('js/**/*.js'))
// .pipe(plugins.concat('cat.js'))
// .pipe(gulp.dest(dest));
// This doesn't (unless you wrap it in a stream-making function)
return gulp.src(src('js/**/*.js'))
.pipe(buildFiles());
});
Любые советы оценены!
Ответы
Ответ 1
Это известная проблема при использовании lazypipe
с gulp 4, и это не будет исправлено в ближайшем будущем. Цитата из этой проблемы:
OverZealous прокомментировал 20 декабря 2015 г.
На данный момент я не собираюсь делать лазиппип на gulp 4.
Насколько я могу судить, эта проблема вызвана тем фактом, что gulp 4 использует async-done
, который имеет это сказать о его поддержка потока:
Примечание. Поддерживаются только фактические потоки, а не потоки faux; Поэтому модули типа event-stream
не поддерживаются.
Когда вы используете lazypipe()
как последний канал, вы получаете поток, который не имеет большого количества свойств, которые вы обычно используете при работе с потоками в gulp. Вы можете сами это увидеть, зарегистрировав потоки:
// console output shows lots of properties
console.log(gulp.src(src('js/**/*.js'))
.pipe(plugins.concat('cat.js'))
.pipe(gulp.dest(dest)));
// console output shows much fewer properties
console.log(gulp.src(src('js/**/*.js'))
.pipe(buildFiles()));
Вероятно, это причина, по которой gulp считает, что второй поток является "фальшивым потоком" и не обнаруживает, когда поток завершен.
Ваш единственный вариант на данный момент - это своего рода обходное решение. Самый простой способ обхода (который не требует дополнительных пакетов) - просто добавить функцию обратного вызова cb
к вашей задаче и прослушать событие 'end'
:
gulp.task('build', function(cb) {
var dest = 'build';
var buildFiles = lazypipe()
.pipe(plugins.concat, 'cat.js')
.pipe(gulp.dest, dest);
gulp.src(src('js/**/*.js'))
.pipe(buildFiles())
.on('end', cb);
});
В качестве альтернативы добавление любого .pipe()
после buildFiles()
должно исправить это, даже тот, который на самом деле ничего не делает gutil.noop()
var gutil = require('gulp-util');
gulp.task('build', function() {
var dest = 'build';
var buildFiles = lazypipe()
.pipe(plugins.concat, 'cat.js')
.pipe(gulp.dest, dest);
return gulp.src(src('js/**/*.js'))
.pipe(buildFiles())
.pipe(gutil.noop());
});
Ответ 2
Так что ошибка понятна. Мне пришлось провести некоторый рефакторинг, чтобы все снова заработало для gulp 4. Я закончил тем, что сделал несколько дополнительных методов, которые берут источник и назначение и выполняют задачи, ранее выполненные моей реализацией lazypipe.
Я должен сказать, что я не скучаю по Lazypipe сейчас. Это просто другой подход. Я закончил с некоторыми дополнительными задачами, но они используют стандартный метод, как в примере ниже:
// previously a lazypipe, now just a method to return from a gulp4 task
const _processJS = (sources, destination) => {
return src(sources)
.pipe(minify(...))
.pipe(uglify(...))
.pipe(obfuscate(...))
.pipe(whatever())
.pipe(dest(destination));
};
const jsTaskXStep1 = ()=>{
return src(...).pipe(...).pipe(...).pipe(dest(...));
};
const jsTaskXStep2 = ()=>{
return _processJS(['./src/js/x/**/*.js'], './dist/js');
};
const jsTaskYStep1 = ()=>{
return src(...).pipe(...).pipe(...).pipe(dest(...));
};
const jsTaskYStep2 = ()=>{
return _processJS(['./src/js/y/**/*.js'], './dist/js');
};
const jsTaskX = series(jsTaskXStep1, jsTaskXStep2);
const jsTaskY = series(jsTaskYStep1, jsTaskYStep2);
module.exports = {
js: parallel(jsTaskX, jsTaskY),
css: ...,
widgets: ...,
...
default: parallel(js, css, widgets, series(...), ...);
}
Таким образом, вы можете поместить свои ленипайпы в методы, подобные _processJS в этом примере. И затем создайте задачи, которые используют это и объедините все с сериями глотка и параллелью. Надеюсь, это поможет некоторым из вас, кто борется с этим.