Gulp4。调用或导入任务时出现“ AssertionError:任务从未定义”

m a*_*sem 12 gulp

在下面可以看到问题的简化视图。基本上,我能叫task1.js使用gulp.series在任务task2,3.js,但一旦我相同的代码添加到通话task1.jstask4.js - Task never defined: task1错误被抛出。与下面的文件结构示例相比,任务文件夹中的任务更多。

我有三个任务,

...
/tasks
   build.js
   clean.js
   dev.js
gulpfile.babel.js
...
Run Code Online (Sandbox Code Playgroud)

使用require-dir包在gulpfile.babel.js中需要所有它们

import requireDir from 'require-dir';
requireDir('./tasks', {recurse: true});
Run Code Online (Sandbox Code Playgroud)

这使我可以从dev.jsclean.js调用任务,并且工作正常。

import gulp from 'gulp';
gulp.task('dev', gulp.series('clean');
Run Code Online (Sandbox Code Playgroud)

但是在build.js中添加了相同的代码结构之后

import gulp from 'gulp';
gulp.task('build', gulp.series('clean');
Run Code Online (Sandbox Code Playgroud)

它以某种方式中断了gulp流(我想),所以现在在任何任务调用上我都得到:
$
gulp dev -AssertionError [ERR_ASSERTION]:任务从未定义:clean


$ gulp -v

[11:50:11] CLI version 2.0.1
[11:50:11] Local version 4.0.0
Run Code Online (Sandbox Code Playgroud)

Mar*_*ark 28

对于从gulp v3迁移到v4或gulp.task()用于在gulp v4中定义任务并获取此错误消息的用户Task never defined,问题通常出在这里:

转发参考

前向引用是指在使用字符串引用编写尚未注册的任务时。这是旧版本中的常见做法,但已删除此功能以实现更快的任务运行时间并促进使用命名函数。在较新的版本中,如果尝试使用前向引用,则会出现错误消息,提示“任务未定义”。尝试将导出用于任务注册和按字符串组成任务时,可能会遇到这种情况。在这种情况下,请使用命名函数而不是字符串引用。

在迁移期间,您可能需要使用前向引用注册表。这将为每个任务引用添加额外的关闭内容,并显着降低构建速度。不要长期依赖此修复程序。

gulpjs文档重新:gulp.seriesgulp.parallel文档

这就是这个意思。有两种创建任务的方法:

1.  gulp.task('someStringAsTask', function() {..})   

2.  function myNamedFunction () {…}
Run Code Online (Sandbox Code Playgroud)

当使用版本1(gulp.task…)时,在注册之前,无法通过其字符串名称引用该任务。所以你不能这样做:

exports.sync = gulp.series('sass2css', serve, watch);
// or gulp.task('dev', gulp.series('sass2css', serve, watch);  doesn't work either    

gulp.task('sass2css', function() {
  return gulp.src(paths.sass.stylesFile)
    .pipe(sass().on("error", sass.logError))
    .pipe(gulp.dest(paths.css.temp))
    .pipe(reload({ stream: true }));
})
Run Code Online (Sandbox Code Playgroud)

结果是

AssertionError [ERR_ASSERTION]: Task never defined: sass2css
Run Code Online (Sandbox Code Playgroud)

这是一个前向引用,它构成一个任务(使用gulp.seriesgulp.parallel),并其注册之前通过其字符串名称(在上述情况下'sass2css')引用该任务。(调用“ ”是注册的行为)首先解决此问题。gulp.task(…..)gulp.task('sass2css',...)

如果使用定义任务的第二版:

function sass2css() {
  return gulp.src(paths.sass.stylesFile)
    .pipe(sass().on("error", sass.logError))
    .pipe(gulp.dest(paths.css.temp))
    .pipe(reload({ stream: true }));
}
Run Code Online (Sandbox Code Playgroud)

您现在正在使用命名函数来注册任务,而无需将其名称用作字符串。所以这现在工作:

exports.sync = gulp.series(sass2css, serve, watch);
// gulp.task('dev', gulp.series(sass2css, serve, watch);  this also works
Run Code Online (Sandbox Code Playgroud)

紧随其后(或先于-可行):

function sass2css() {
  return gulp.src(paths.sass.stylesFile)
    .pipe(sass().on("error", sass.logError))
    .pipe(gulp.dest(paths.css.temp))
    .pipe(reload({ stream: true }));
}
Run Code Online (Sandbox Code Playgroud)

原始的OP使用了此方法,并且有效:

import gulp from 'gulp';
gulp.task('dev', gulp.series('clean');
Run Code Online (Sandbox Code Playgroud)

注意那clean.js是以前进口的,dev.js所以还可以。

这不起作用:

import gulp from 'gulp';
gulp.task('build', gulp.series('clean');
Run Code Online (Sandbox Code Playgroud)

因为使用字符串引用的任务'clean'build.js在引用位置之后导入(并进行注册),因此会创建对字符串引用任务的非法前向引用

因此,有两种解决此错误的标准方法:

  1. 使用命名函数不定义任务gulp.task('someTask',...)。然后,在编写其他任务时(即使用gulp.series或时),使用这些命名函数的顺序并不重要gulp.parallel。使用命名函数还有其他优点,例如传递参数,因此这是最佳选择。

  2. 如果你使用旧的一口V3 gulp.task与字符串引用创建任务的方法,注意不是指那些任务,直到任务实际创建。

另请参阅我对任务“永不定义的错误”的回答,以解决导致相同错误消息的另一个问题。 特别gulp.task('someTask', ['anotherTask'], function(){})是在gulp4文件中使用synatx。


小智 10

gulp 4的seriesparallel函数并没有像它的自述文件所暗示的那样创建任务定义,而是它们都在参数中运行任务。为了按预期工作,需要用闭包包围调用。

因此,要修复摘录

gulp.task('build', gulp.series('clean'));
Run Code Online (Sandbox Code Playgroud)

有必要添加闭包:

// Older EcmaScripts:
gulp.task('build', function() { return gulp.series('clean') });

// EcmaScript 6:
gulp.task('build', () => gulp.series('clean'));
Run Code Online (Sandbox Code Playgroud)