在 Gulp 4 中动态创建文件的系列执行任务

Executing tasks in series which creates file dynamically in Gulp 4

我最近从使用 Gulp 3 迁移到 Gulp 4。引入 gulp.src()gulp.parallel() 等新任务增加了更多的灵活性和易用性。
这是我尝试按顺序执行任务的代码。

  1. 动态创建文件的异步任务

    让 css_purge_libs = 异步 () => {
    var pacs = ["!bootstrap", "bulma", "animate.css"];
    var paths = await fetch_resources(pacs, "bower", "css|sass");
    return gulp.src(路径)
      .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"));
    };
    

写上面的代码是为了从 bower 特定包中获取 .css or .sass 文件,在 bower.json 中没有提到 main 属性(不需要额外的插件,例如 wiredep)。文件将在 temp 文件夹中即时创建。

  1. 构建、连接和 sourcemap 生成

    让 css_build = () => {
    让路径 = [`${config.css.destination.temp}/**/*.css`, `${config.css.destination.dev}**/*.css`];
    return gulp.src(路径)
      .pipe(之前(真, config.css.destination.build)())
      .pipe(P.postcss(config.css.postcss.plugins))
      .pipe(P.if(产品, P.sourcemaps.init()))
      .pipe(P.if(产品, P.cssnano()))
      .pipe(P.if(产品, P.concat("ariyana-build.css")))
      .pipe(P.if(产品, P.rev()))
      .pipe(P.if(产品, P.sourcemaps.write(".")))
      .pipe(gulp.dest(config.css.destination.build));
    }
    

获取的资源和项目资源将通过流发送进行处理。

  1. 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 资源中获取动态创建的文件。我能想到发生这种情况的原因,因为 IO op 发生在引擎盖下可能是异步操作,所以 gulp 不知道操作是否完成

答案场景

let sloop = ()=> {
  return new Promise(resolve=> {
    setTimeout(resolve, 2000);
  });
}

当我添加一点 tweek 时会带来延迟并在任务定义中引入

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. 有没有更好的方法来处理这些情况?

不幸的是,这是 gulp 中的一个已知问题,没有解决方法:https://github.com/gulpjs/gulp/issues/1421

你 return 从你的任务中得到的信息告诉 gulp 如何等待:你可以 return 一个流(gulp 等待它完成),或者一个 Promise (gulp 等待它解决),等等。你 不能 做的是 return 一个 Promise对于 Stream.

目前的解决方案是手动等待 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);
    });
};

这很丑陋,但目前没有更好的方法在单个任务中执行 标准异步调用 流管理。