Выполнение задач в серии, которая динамически создает файл в Gulp 4
Недавно я перешел с использования Gulp 3 на Gulp 4. Представляем новые задачи, такие как gulp.src()
а также gulp.parallel()
добавляет больше гибкости и простоты использования.
Вот мой код, пытающийся выполнять задачи последовательно.
Асинхронная задача, которая создает файлы динамически
let css_purge_libs = async () => { var pacs = ["!bootstrap", "bulma", "animate.css"]; var paths = await fetch_resources(pacs, "bower", "css|sass"); возврат gulp.src (пути) .pipe(before(true, config.css.destination.temp + "/lib")()) .pipe(P.if(/\.sass$/ г, P.sass().on('ошибка', P.sass.logError))) .pipe(P.purgecss(config.css.purgecss)) .pipe(gulp.dest(config.css.destination.temp + "/lib")); };
написал код выше, чтобы получить .css or .sass
файлы из конкретных пакетов Bower, о которых не упоминалось main
недвижимость в bower.json
(не нужен дополнительный плагин, как wiredep
). файлы будут созданы на лету в temp
папка.
Построение, создание конкатов и исходных карт
let css_build = () => { let paths = [`${config.css.destination.temp}/**/*.css`, `${config.css.destination.dev}**/*.css`]; возврат gulp.src (пути) .pipe(before(true, config.css.destination.build)()) .pipe(P.postcss(config.css.postcss.plugins)) .pipe(P.if(prod, P.sourcemaps.init())) .pipe(P.if(prod, P.cssnano())) .pipe(P.if(prod, P.concat("ariyana-build.css"))) .pipe(P.if(prod, P.rev())) .pipe(P.if(prod, P.sourcemaps.write("."))) .pipe(gulp.dest(config.css.destination.build)); }
извлеченные ресурсы и ресурсы проекта будут отправлены через поток для обработки.
Определения задач Gulp
gulp.task('css:purge-libs', css_purge_libs); gulp.task('css:build', css_build); gulp.task("serve:dev", gulp.series(css_purge_libs, css_build, serve_dev));
Сценарий проблемы
Когда я выпускаю gulp serve:dev
, что происходит, прикреплено в журналах ниже.
[00:19:19] Using gulpfile D:\Enterprise\test\gulpfile.js
[00:19:19] Starting 'serve:dev'...
[00:19:19] Starting 'css_purge_libs'...
[00:19:21] Finished 'css_purge_libs' after 1.86 s
[00:19:21] Starting 'css_build'...
[00:19:25] bower_components\bulma\bulma.sass
[00:19:25] app\styles\bootstrap-reboot.css
[00:19:25] bower_components\animate.css\animate.css
[00:19:26] app\styles\main.css
[00:19:26] Finished 'css_build' after 4.69 s
[00:19:26] Starting 'serve_dev'...
[00:19:26] Finished 'serve_dev' after 1.57 ms
[00:19:26] Finished 'serve:dev' after 6.57 s
похоже глоток не поднял динамически созданные файлы в .tmp/styles/lib
Ресурсы CSS. Я мог бы подумать причину, что происходит, потому что операция ввода-вывода происходит под капотом, может быть асинхронной операцией, так что gulp не имеет ни малейшего понятия, выполнена ли операция
Сценарий ответа
let sloop = ()=> {
return new Promise(resolve=> {
setTimeout(resolve, 2000);
});
}
когда я добавляю немного твика, который приносит задержку и вводится в определение задачи
gulp.task('css:purge-libs', css_purge_libs);
gulp.task('css:build', css_build);
gulp.task("serve:dev", gulp.series(css_purge_libs, sloop, css_build, serve_dev));
это пришло как выходной журнал, который я ожидал.
[00:28:58] Using gulpfile D:\Enterprise\test\gulpfile.js
[00:28:58] Starting 'serve:dev'...
[00:28:58] Starting 'css_purge_libs'...
[00:29:00] Finished 'css_purge_libs' after 1.8 s
[00:29:00] Starting 'sloop'...
[00:29:00] bower_components\bulma\bulma.sass
[00:29:00] bower_components\animate.css\animate.css
[00:29:02] Finished 'sloop' after 2.18 s
[00:29:02] Starting 'css_build'...
[00:29:08] .tmp\styles\lib\animate.css
[00:29:08] .tmp\styles\lib\bulma.css
[00:29:08] app\styles\bootstrap-reboot.css
[00:29:08] app\styles\main.css
[00:29:08] Finished 'css_build' after 6.43 s
[00:29:08] Starting 'serve_dev'...
[00:29:08] Finished 'serve_dev' after 2.96 ms
[00:29:08] Finished 'serve:dev' after 10 s
введение новой задержки между асинхронными операциями решило мою проблему
Вопросы
- Почему это происходит?(Пожалуйста, дайте мне подробное объяснение, потому что я ищу внутренности)
- Почему Gulp Stream не может опрашивать, если файл был создан или нет.
- Есть ли лучший способ справиться с такими сценариями?
1 ответ
К сожалению, это известная проблема в gulp, которая не имеет обходного пути: https://github.com/gulpjs/gulp/issues/1421
То, что вы возвращаете из своей задачи, говорит gulp, как ждать: вы можете вернуть Stream (gulp ждет его завершения) или Promise (gulp ждет его разрешения) и т. Д. Что вы не можете сделать, так как пытаетесь сделать, это вернуть обещание для потока.
Решение, на данный момент, заключается в том, чтобы вручную дождаться окончания потока gulp внутри вашей асинхронной функции, например, так:
let myTask = async () => {
let files = await getFilePaths();
return new Promise((resolve, reject) => {
return gulp.src(files)
.pipe(gulp.dest('someplace'))
.on('end', resolve)
.on('error', reject);
});
};
Это некрасиво, но в настоящее время нет лучшего способа выполнять как стандартные асинхронные вызовы, так и управление потоками в одной задаче.