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

问题描述 投票:0回答:4

您可以在下面看到问题的简化视图。基本上,我可以在任务 task2、3.js 中使用 gulp.series 调用 task1.js,但是一旦我添加相同的代码以在 task4.js 中调用 task1.js -

Task never defined: task1
错误被抛出。 任务文件夹中的任务比下面的文件结构示例中的任务多。

我有三个任务,

...
/tasks
   build.js
   clean.js
   dev.js
gulpfile.babel.js
...

所有这些都需要在 gulpfile.babel.js 中使用 require-dir 包

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

这允许我从 clean.jsdev.js 调用任务,它工作正常。

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

但是在我在 build.js.

添加相同的代码结构之后
import gulp from 'gulp';
gulp.task('build', gulp.series('clean');

它以某种方式打破了 gulp 流(我猜),所以现在在任何任务调用中我得到:
$gulp 开发
-AssertionError [ERR_ASSERTION]: Task never defined: clean.


$gulp -v

[11:50:11] CLI version 2.0.1
[11:50:11] Local version 4.0.0
gulp
4个回答
62
投票

对于那些从 gulp v3 迁移到 v4 或正在使用

gulp.task()
在 gulp v4 中定义任务并收到此错误消息:
Task never defined
的人,问题通常出在这里:

转发参考

前向引用是当你编写任务时,使用字符串 引用,尚未注册。这是一个常见的 在旧版本中实践,但此功能已被删除以实现 更快的任务运行时间并促进命名函数的使用。在较新的 版本,你会得到一个错误,消息“任务从未定义”, 如果您尝试使用前向引用。您可能会遇到这种情况 尝试将导出用于您的任务注册和组合任务 按字符串。在这种情况下,使用命名函数而不是字符串 参考资料

在迁移过程中,您可能需要使用前向引用注册表。 这将为每个任务引用添加一个额外的闭包,并且 大大减慢您的构建速度。不要太依赖这个修复 长

来自 gulpjs 文档:gulp.seriesgulp.parallel 文档.

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

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.series
gulp.parallel
)并通过其字符串名称引用一个任务(在上述情况下
'sass2css'
before它已被注册。 (调用“
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.series
    gulp.parallel
    时,使用这些命名函数的顺序并不重要。而且使用命名函数还有其他优点,比如传递参数,所以这是最好的选择。

  2. 如果您确实使用较旧的 gulp v3

    gulp.task
    方法创建带有字符串引用的任务,请注意在实际创建任务之前after之前不要引用这些任务。

另请参阅我在 task never defined error 的答案,以修复导致相同错误消息的另一个问题。 特别是在 gulp4 文件中使用

gulp.task('someTask', ['anotherTask'], function(){})
synatx。


14
投票

gulp 4 的

series
parallel
函数不会创建任务定义,因为它的 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'));

3
投票

我有一个类似的设置,我在目录下递归

require
所有任务。更新到 gulp 4 后开始出现错误Task never defined.

我尝试了 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'));

0
投票

最简单的解决方案可能是使用官方的 undertaker-forward-reference 包:

const gulp = require("gulp");
const FwdRef = require("undertaker-forward-reference");

gulp.registry(FwdRef()); // Or gulp.registry(new FwdRef());

gulp.task("firstRegisteredTask", gulp.series("laterRegisteredTask")); // Works thanks to undertaker-forward-reference

gulp.task("laterRegisteredTask", () => {
  return gulp.src("someGlob").pipe(gulp.dest("someFolder"));
});

此解决方案可能会对性能产生负面影响(来源):

这将为每个任务引用添加一个额外的闭包,并显着减慢您的构建速度。

© www.soinside.com 2019 - 2024. All rights reserved.