在 Gulp 4 中动态创建文件的系列执行任务
Executing tasks in series which creates file dynamically in Gulp 4
我最近从使用 Gulp 3 迁移到 Gulp 4。引入 gulp.src()
和 gulp.parallel()
等新任务增加了更多的灵活性和易用性。
这是我尝试按顺序执行任务的代码。
动态创建文件的异步任务
让 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
文件夹中即时创建。
构建、连接和 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));
}
获取的资源和项目资源将通过流发送进行处理。
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
在异步操作之间引入新的延迟解决了我的问题
问题
- 为什么会这样?(请给我详细的解释,因为我正在寻找内部结构)
- 为什么 gulp 流无法轮询文件是否已创建。
- 有没有更好的方法来处理这些情况?
不幸的是,这是 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);
});
};
这很丑陋,但目前没有更好的方法在单个任务中执行 标准异步调用 和 流管理。
我最近从使用 Gulp 3 迁移到 Gulp 4。引入 gulp.src()
和 gulp.parallel()
等新任务增加了更多的灵活性和易用性。
这是我尝试按顺序执行任务的代码。
动态创建文件的异步任务
让 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
文件夹中即时创建。
构建、连接和 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)); }
获取的资源和项目资源将通过流发送进行处理。
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
在异步操作之间引入新的延迟解决了我的问题
问题
- 为什么会这样?(请给我详细的解释,因为我正在寻找内部结构)
- 为什么 gulp 流无法轮询文件是否已创建。
- 有没有更好的方法来处理这些情况?
不幸的是,这是 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);
});
};
这很丑陋,但目前没有更好的方法在单个任务中执行 标准异步调用 和 流管理。