Выполнение задач в серии, которая динамически создает файл в Gulp 4 - PullRequest
0 голосов
/ 26 декабря 2018

Я недавно перешел с использования Gulp 3 на Gulp 4. Представление новых задач, таких как gulp.src() и gulp.parallel(), добавляет больше гибкости и простоты использования.
Вот мой код, пытающийся выполнить задачи последовательно.

  1. Асинхронная задача, которая создает файлы динамически

    let css_purge_libs = async () => {
    var pacs = ["!bootstrap", "bulma", "animate.css"];
    var paths = await fetch_resources(pacs, "bower", "css|sass");
    return gulp.src(paths)
      .pipe(before(true, config.css.destination.temp + "/lib")())
      .pipe(P.if(/\.sass$/gm, P.sass().on('error', 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`];
return gulp.src(paths)
  .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

похоже, что gulp не обнаружил динамически созданные файлы в ресурсах .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

введение новой задержки между асинхронными операциями решило мою проблему

Вопросы

  1. Почему это происходит? (Пожалуйста, дайте мне подробное объяснениепотому что я ищу внутренности)
  2. Почему поток gulp не может опрашивать, если файл был создан при создании или нет.
  3. Есть ли лучший способ справиться с такими сценариями?

1 Ответ

0 голосов
/ 27 декабря 2018

К сожалению, это известная проблема в gulp, которая не имеет обходного пути: https://github.com/gulpjs/gulp/issues/1421

То, что вы возвращаете из своей задачи, говорит gulp, как ждать: вы можете вернуть поток (gulp ждетили «Обещание» (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);
    });
};

Это уродливо, но в настоящее время нет лучшего способадля выполнения обоих стандартных асинхронных вызовов и управления потоками в одной задаче.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...