本文介绍了依次执行任务,从而在Gulp 4中动态创建文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近从使用Gulp 3迁移到了Gulp4.引入了诸如 gulp.src() gulp.parallel()之类的新任务,可以提高灵活性和使用方便.
这是我的代码,试图按顺序执行任务.

I've recently migrated from using Gulp 3 to Gulp 4. Introducing the new tasks like gulp.src() and gulp.parallel() adds more flexibility and ease of use.
Here is my code attempting to execute tasks in series.

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

  1. Asynchronous task which creates files dynamically


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"));
};

编写上面的代码,以便从专用于Bower的程序包中获取 .css或.sass 文件,而在 bower.json main 属性,/code>(不需要其他插件,例如 wiredep ).文件将在 temp 文件夹中动态创建.

wrote above code in order to fetch .css or .sass files from bower specific packages which there was no mentioned of main property in bower.json(don't need an additional plugin like wiredep). files will be created on the fly in temp folder.

  1. 生成建筑,concat和源地图

  1. Building, concat and sourcemap generation


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));
}

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

fetched resources and project resources will be sent through a stream for processing.

  1. Gulp任务定义

  1. Gulp task definitions


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 时,发生的情况附在下面的日志中.

When i issue gulp serve:dev, what happens is attached in below logs.

[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发生在引擎盖下可能是异步ops,所以gulp不知道op是否完成

looks like gulp did not picked up the dynamically created files in the .tmp/styles/lib css resources. I could think a reason what happens because the IO op happens under the hood could be an async ops so gulp does not have a clue whether the op is done

答案方案

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

当我增加一个星期的时间,这会带来延迟并在任务定义中引入

when i add a little bit of a tweek which brings a delay and introduced in the task definition

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));

这是我期望的输出日志.

this came as the output log which i was expected.

[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

在异步操作之间引入新的延迟解决了我的问题

introducing a new delay between async ops solved my problem

问题

  1. 为什么会这样?(请给我深入的解释,因为我正在寻找内部零件)
  2. 为什么gulp流无法轮询文件是否已完成创建.
  3. 有没有更好的方法来处理这种情况?

推荐答案

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

Unfortunately, this is a known issue in gulp that doesn't have a workaround: https://github.com/gulpjs/gulp/issues/1421

您从任务中返回的内容告诉gulp如何等待:您可以返回一个Stream(gulp等待它完成),或一个Promise(gulp等待它解决),等等.您不能要做的就是返回流的承诺.

What you return from your task tells gulp how to wait: you can return a Stream (gulp waits for it to finish), or a Promise (gulp waits for it to resolve), etc. What you cannot do, as you are trying to do, is return a Promise for a Stream.

目前的解决方案是手动等待gulp流在异步函数中结束,例如:

The solution, for now, is to manually wait for your gulp stream to end inside your async function, like so:

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);
    });
};

这很丑陋,但是目前尚没有更好的方法来在单个任务中同时进行 和标准的异步调用流管理.

It's ugly, but there's not currently a better way to do both standard async calls and stream management in a single task.

这篇关于依次执行任务,从而在Gulp 4中动态创建文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 06:11