Javascript 在通过gulp子模块注入依赖项的模块上运行gulp任务失败,而通过gulp子模块注入依赖项的模块又有自己的依赖项

Javascript 在通过gulp子模块注入依赖项的模块上运行gulp任务失败,而通过gulp子模块注入依赖项的模块又有自己的依赖项,javascript,node.js,gulp,Javascript,Node.js,Gulp,标题听起来可能有点模糊,但这里有一个例子说明了问题所在。假设我们有三个模ModuleA,ModuleB和ModuleC,因此ModuleA依赖于ModuleB,ModuleB依赖于ModuleC。当我们需要针对ModuleA运行任务时,我们通常还需要针对其依赖项—ModuleB和ModuleC—运行一些任务,这就是gulp子模块发挥作用的地方。Gulp子模块让我们定义依赖模块的任务与其依赖项之间的依赖关系,以便依赖模块的任务触发其依赖项的相应任务 如果我们有一个扁平的结构,也就是说,某个模块依赖

标题听起来可能有点模糊,但这里有一个例子说明了问题所在。假设我们有三个模ModuleA,ModuleB和ModuleC,因此ModuleA依赖于ModuleB,ModuleB依赖于ModuleC。当我们需要针对ModuleA运行任务时,我们通常还需要针对其依赖项—ModuleB和ModuleC—运行一些任务,这就是gulp子模块发挥作用的地方。Gulp子模块让我们定义依赖模块的任务与其依赖项之间的依赖关系,以便依赖模块的任务触发其依赖项的相应任务

如果我们有一个扁平的结构,也就是说,某个模块依赖于一堆其他模块,而这些模块本身没有依赖关系,那么这种方法就非常有效。然而,一旦这些依赖项中的任何一个有了自己的依赖项,整个生态系统就会因为一条模糊的错误消息而崩溃,该消息告诉我们gulp无法找到某个任务

这是演示代码。要在本地环境中测试这一点,必须至少将gulp作为全局包安装,并将gulp和gulp子模块作为项目的本地包安装

模块-a.gulpfile.js

const gulp = require("gulp");
require("gulp-submodule")(gulp);

gulp.submodule("module-b", {filepath: "module-b.gulpfile.js"});

gulp.task("default", ["module-b:default"], () => {
    console.log("Running task 'default' for module 'module-a'...");
});
const gulp = require("gulp");
require("gulp-submodule")(gulp);

gulp.submodule("module-c", {filepath: "module-c.gulpfile.js"});

gulp.task("default", ["module-c:default"], () => {
    console.log("Running task 'default' for module 'module-b'...");
});
const gulp = require("gulp");

gulp.task("default", [], () => {
    console.log("Running task 'default' for module 'module-c'...");
});
模块-b.gulpfile.js

const gulp = require("gulp");
require("gulp-submodule")(gulp);

gulp.submodule("module-b", {filepath: "module-b.gulpfile.js"});

gulp.task("default", ["module-b:default"], () => {
    console.log("Running task 'default' for module 'module-a'...");
});
const gulp = require("gulp");
require("gulp-submodule")(gulp);

gulp.submodule("module-c", {filepath: "module-c.gulpfile.js"});

gulp.task("default", ["module-c:default"], () => {
    console.log("Running task 'default' for module 'module-b'...");
});
const gulp = require("gulp");

gulp.task("default", [], () => {
    console.log("Running task 'default' for module 'module-c'...");
});
模块-c.gulpfile.js

const gulp = require("gulp");
require("gulp-submodule")(gulp);

gulp.submodule("module-b", {filepath: "module-b.gulpfile.js"});

gulp.task("default", ["module-b:default"], () => {
    console.log("Running task 'default' for module 'module-a'...");
});
const gulp = require("gulp");
require("gulp-submodule")(gulp);

gulp.submodule("module-c", {filepath: "module-c.gulpfile.js"});

gulp.task("default", ["module-c:default"], () => {
    console.log("Running task 'default' for module 'module-b'...");
});
const gulp = require("gulp");

gulp.task("default", [], () => {
    console.log("Running task 'default' for module 'module-c'...");
});
在module-a.gulpfile.js上运行任务“default”后,您将获得类似以下内容的输出:

gulp——gulpfile模块-a.gulpfile.js
[07:15:27]使用gulpfile模块-a.gulpfile.js
[07:15:27]任务“模块b:模块c:默认值”不在您的gulpfile中
[07:15:27]请检查文档中的gulpfile格式是否正确


有人可能会注意到,gulp正在寻找一个名为“module-b:module-c:default”的特定任务,尽管在任何项目文件中都没有定义或引用具有此名称的任务。

这个奇怪的不存在的任务来自gulp子模块处理模块和任务之间依赖关系的方式。简单地说,它做了以下工作:

  • 首先,在这次调用中,
    gulp.submodule(“module-b”,{filepath:“module-b.gulpfile.js”})
    gulp子模块临时替换原始的
    gulp.task
    ,并将指定的gulpfile作为模块加载
  • 加载gulpfile时,它将获得修改后的gulp实例,其中task方法通过在提交的任务名称前面加上模块名和分隔符(默认情况下为“:”)来修改作为其参数提交的任务的名称
  • 稍后,当gulp运行模块“module-a”的任务“default”时,它遇到了一个依赖项,我们将其引用为“module-b:default”,这正是在步骤2中为模块“module-b”的任务“default”构造的特殊名称
  • 对于多个级别的依赖层次结构,这种简单的逻辑会中断,因为从module-b.gulpfile.js调用
    gulp.submodule(“module-c”),{filepath:“module-c.gulpfile.js”}
    会导致包装
    gulp.task
    通过第二次吞咽子模块,因此模块“module-c”的任务“default”的名称前面加了两次:首先加上“module-c”,然后加上“module-b”

    为了快速修复此问题,我已向原始子模块()的私有模块提交了一个快捷方式修复。这只是一个快速的解决方案,肯定不是最好的,但它为我做到了。我会更新这个答案,我会为这个问题提供一个更坚实的解决方案吗