Reputation: 1141
I want to define a Gulp 4 task that is a composition of three functions executed in series. However, I want to define it as a named function rather than using gulp.task()
:
function beforeTest() { ... }
function coreTest() { ... }
function afterTest() { ... }
export function test() {
// what goes here?
// this function should be equivalent to:
// gulp.task('test', gulp.series(beforeTest, coreTest, afterTest));
}
I found a similar question asked on the Gulp GitHub issue tracker where the OP tried the equivalent of the following:
export function test() {
return gulp.series(beforeTest, coreTest, afterTest);
}
The reason why this does not work is explained in the GitHub issue. The recommended solution from the Gulp team was to not use a named function but to rather assign the composite function to a variable:
export const test = gulp.series(beforeTest, coreTest, afterTest);
However, this solution appears deficient for a few reasons.
The first deficiency was raised in a comment on the GitHub issue about the restriction this places on task ordering (something I was already trying to avoid by using named functions instead of gulp.task()
due to the new requirement in Gulp 4 that task names must be registered before they are referenced).
The second deficiency is more cosmetic (and thus triggers my OCD :-) ). When running gulp test
, the composite test
task is displayed in the output:
[00:00:00] Starting 'test'...
[00:00:00] Starting 'beforeTest'...
[00:00:00] Finished 'beforeTest' after 106 ms
[00:00:00] Starting 'coreTest'...
[00:00:00] Finished 'coreTest' after 214 ms
[00:00:00] Starting 'afterTest'...
[00:00:00] Finished 'afterTest' after 280 μs
[00:00:00] Finished 'test' after 324 ms
However, if I have another composite task that references test
, such as:
gulp.task('build', gulp.parallel(lint, test));
Then when I run gulp build
, the composite test
task is not displayed in the output:
[00:00:00] Starting 'build'...
[00:00:00] Starting 'lint'...
[00:00:00] Starting 'beforeTest'...
[00:00:01] Finished 'beforeTest' after 1.08 s
[00:00:01] Starting 'coreTest'...
[00:00:02] Finished 'coreTest' after 977 ms
[00:00:02] Starting 'afterTest'...
[00:00:02] Finished 'afterTest' after 232 μs
[00:00:07] Finished 'lint' after 6.96 s
[00:00:07] Finished 'build' after 6.96 s
I suspect this may be because Gulp does not display any function whose name is series
or parallel
. I tried setting test.displayName
, as suggested in the GitHub issue:
export const test = gulp.series(beforeTest, coreTest, afterTest);
test.displayName = 'test';
But that didn't change the output of gulp build
. I also tried setting test.name
, but that property appears to be frozen:
TypeError: Cannot assign to read only property 'name' of function 'function series(done) {
nowAndLater.mapSeries(args, asyncDone, extensions, done);
}'
It seems that if I could define the composite test
task as a named function, it would address both of these deficiencies. So, in summary, how would I define the body of the test
function shown at the top of this question?
Upvotes: 3
Views: 4179
Reputation: 1141
export function test(...args) {
return gulp.series(beforeTest, coreTest, afterTest)(...args);
}
The function arguments must be passed through to the composite function returned by gulp.series()
in the event any component function requires the Gulp task callback parameter (i.e. cb
, done
, whatever).
This task definition produces the desired output when running gulp build
:
[00:00:00] Starting 'build'...
[00:00:00] Starting 'lint'...
[00:00:00] Starting 'test'...
[00:00:00] Starting 'beforeTest'...
[00:00:01] Finished 'beforeTest' after 1.06 s
[00:00:01] Starting 'coreTest'...
[00:00:02] Finished 'coreTest' after 949 ms
[00:00:02] Starting 'afterTest'...
[00:00:02] Finished 'afterTest' after 302 μs
[00:00:02] Finished 'test' after 2.05 s
[00:00:07] Finished 'lint' after 7.12 s
[00:00:07] Finished 'build' after 7.12 s
EDIT: A deficiency of this solution is that by deferring the call to gulp.series()
until the test
task is actually executed, the child tasks do not show up in the task map displayed by gulp --tasks
.
For example, using the proposed solution, the output of gulp --tasks
is
[00:00:00] Tasks for ~/gulpfile.babel.js
[00:00:00] └── test
Whereas, defining test
as a variable as suggested in the original GitHub issue, the output is
[00:00:00] Tasks for ~/gulpfile.babel.js
[00:00:00] └─┬ test
[00:00:00] └─┬ <series>
[00:00:00] ├── beforeTest
[00:00:00] ├── coreTest
[00:00:00] └── afterTest
This isn't an issue for the question posed because the beforeTest
, coreTest
, and afterTest
functions are not actual tasks (i.e. they are not export
ed), so I actually do not want them to show up. But, because I can easily see getting into the same situation with export
ed subtasks, I don't feel this solution is completely intellectually satisfying.
Upvotes: 3