问题描述
我最近从使用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.
-
动态创建文件的异步任务
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.
-
生成建筑,concat和源地图
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.
-
Gulp任务定义
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
问题
- 为什么会这样?(请给我深入的解释,因为我正在寻找内部零件)
- 为什么gulp流无法轮询文件是否已完成创建.
- 有没有更好的方法来处理这种情况?
推荐答案
不幸的是,这是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中动态创建文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!