Gulp4。 " AssertionError:任务从未定义"在调用或导入任务时

时间:2018-05-24 09:05:58

标签: gulp

您可以在下面看到问题的简化视图。基本上,我可以在任务 task2,3.js 中使用gulp.series调用 task1.js ,但是一旦我添加相同的代码来调用 task4.js 中的task1.js - $('#ProductList').val()错误被抛出。 任务文件夹中的任务多于下面的文件结构示例。

我有三项任务,

Task never defined: task1

使用require-dir软件包

在gulpfile.babel.js中需要它们
...
/tasks
   build.js
   clean.js
   dev.js
gulpfile.babel.js
...

这允许我通过 dev.js clean.js 调用任务,它运行正常。

import requireDir from 'require-dir';
requireDir('./tasks', {recurse: true});

但是我在 build.js 添加了相同的代码结构。

import gulp from 'gulp';
gulp.task('dev', gulp.series('clean');

它以某种方式打破了gulp stream(我猜),所以现在我得到的任何任务调用:
$ gulp dev
-AssertionError [ERR_ASSERTION]:任务从未定义:清理

$ gulp -v

import gulp from 'gulp';
gulp.task('build', gulp.series('clean');

3 个答案:

答案 0 :(得分:12)

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

  

转发参考

     

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

     

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

来自gulpjs documentation re: gulp.seriesgulp.parallel documentation

这是什么意思。创建任务有两种方法:

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

2.  function myNamedFunction () {…}

使用版本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 }));
})

结果

AssertionError [ERR_ASSERTION]: Task never defined: sass2css

这是一个前向引用,它构成一个任务(使用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 }));
}

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

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

其后(或在前面-可以使用):

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

最初的OP使用了它,并且有效:

import gulp from 'gulp';
gulp.task('dev', gulp.series('clean');

请注意,clean.js是在dev.js之前导入的,所以可以。

这不起作用:

import gulp from 'gulp';
gulp.task('build', gulp.series('clean');

由于字符串引用的任务,'clean'在被引用的build.js之后被导入(并注册),从而创建了非法的转发引用,引用的任务。

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

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

  2. 如果确实使用了较早的gulp v3 gulp.task方法来创建带有字符串引用的任务,请注意不要在实际创建任务后之后引用这些任务。

另请参见我在task never defined error上的答案,以解决导致相同错误消息的另一个问题。特别是在gulp4文件中使用gulp.task('someTask', ['anotherTask'], function(){}) synatx。

答案 1 :(得分:2)

我有一个类似的设置,其中我将所有任务递归require放在目录下。并且在更新到gulp 4后开始出现错误任务从未定义

我尝试了Pedro解决方案,但这引起了另一个错误:

The following tasks did not complete: default
Did you forget to signal async completion?

对于我来说,解决方案非常简单,只需导入缺少的任务即可。

import gulp from 'gulp';
import './clean';

gulp.task('build', gulp.series('clean'));

答案 2 :(得分:1)

gulp 4的seriesparallel函数并未按照其README的建议创建任务定义,而是它们都在参数中运行任务。为了按预期方式工作,需要用闭包将调用括起来。

所以,要修复摘录

gulp.task('build', gulp.series('clean'));

有必要添加闭包:

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

// EcmaScript 6:
gulp.task('build', () => gulp.series('clean'));