您可以在下面看到问题的简化视图。基本上,我可以在任务 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.js 在 dev.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 v3 迁移到 v4 或正在使用
gulp.task()
在 gulp v4 中定义任务并收到此错误消息:Task never defined
的人,问题通常出在这里:
转发参考
前向引用是当你编写任务时,使用字符串 引用,尚未注册。这是一个常见的 在旧版本中实践,但此功能已被删除以实现 更快的任务运行时间并促进命名函数的使用。在较新的 版本,你会得到一个错误,消息“任务从未定义”, 如果您尝试使用前向引用。您可能会遇到这种情况 尝试将导出用于您的任务注册和组合任务 按字符串。在这种情况下,使用命名函数而不是字符串 参考资料
在迁移过程中,您可能需要使用前向引用注册表。 这将为每个任务引用添加一个额外的闭包,并且 大大减慢您的构建速度。不要太依赖这个修复 长
来自 gulpjs 文档:gulp.series 和 gulp.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
之后被导入(并因此注册)——因此创建了一个非法的前向引用 到一个字符串引用的任务。
所以有两种标准的方法来修复这个错误:
使用命名函数来定义任务不是
gulp.task('someTask',...)
。那么在编写其他任务时,即使用 gulp.series
或 gulp.parallel
时,使用这些命名函数的顺序并不重要。而且使用命名函数还有其他优点,比如传递参数,所以这是最好的选择。如果您确实使用较旧的 gulp v3
gulp.task
方法创建带有字符串引用的任务,请注意在实际创建任务之前after之前不要引用这些任务。另请参阅我在 task never defined error 的答案,以修复导致相同错误消息的另一个问题。 特别是在 gulp4 文件中使用
gulp.task('someTask', ['anotherTask'], function(){})
synatx。
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'));
我有一个类似的设置,我在目录下递归
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'));
最简单的解决方案可能是使用官方的 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"));
});
此解决方案可能会对性能产生负面影响(来源):
这将为每个任务引用添加一个额外的闭包,并显着减慢您的构建速度。