【问题标题】:Conditionally invoking GulpJS tasks (manually)有条件地调用 GulpJS 任务(手动)
【发布时间】:2016-01-31 06:41:07
【问题描述】:

我想构建一个 gulp 任务,它会在运行之前有条件地手动调用其他一些任务。在看到 gulp.run('task') 已被弃用后,我最终得到了这个基本结构:

const build = {
    server: () => {
        return gulp.src(files.server)
            ...
            .pipe(gulp.dest(files.outDir))
    },

    web: () => {
        return gulp.src(files.web)
            ...
            .pipe(gulp.dest(files.outDir))
    }
}

gulp.task('serve', () => {
    // run the server and if necessary, force it to stop first
    const start = () => expressServer.start('./dist/main.js')

    // don't try to run if build hasn't been run first
    try {
        fs.statSync('./dist/main.js') // throws an exception if the file doesn't exist
        start()
    } catch (err) {
        // ----- TODO in parallel; build server and web
        // afterwards; run server iff there were no errors

        if (failed)
            console.error(err)
        else
            start()
    }
})

看起来调用 build.server()build.web() 确实会运行 gulp 任务,但函数会立即返回 - 我猜这意味着这些函数的主体是异步运行的?

谁能帮我理解:

  • gulp.src(...). ... .gulp.dest(...) 链实际上返回了什么?我怀疑 gulp 是否异步运行这些操作?
  • 假设异步操作;我该如何等待这些完成?
  • 如果不是异步的,我该如何执行它们?

【问题讨论】:

  • 对于同步操作,另见这里➝stackoverflow.com/a/26390567/444255。使“第三”成为一项独特的任务,并依赖于“第二”和“第一”。还要使“第二”取决于“第一”。这应该保证等待对方完成。
  • @FrankN 一个很好的建议,但我想不出一个适合 OP 上下文的好方法(因为 OP 想在代码中有条件地启动任务)。如果您知道我有兴趣从您那里得到答案,那么我也有机会学到一些东西:-)
  • @FrankN 谢谢。我试图避免同步任务,因为我将整个 node_modules 目录复制到我的 dist 文件夹中(可以理解,这需要很长时间 - 但我已经解决了这个问题)。我仍然(慢慢地)对 Gulp 有所了解,最后我对一些并不真正需要它的东西采用了一种非常复杂的方法!

标签: javascript node.js asynchronous gulp


【解决方案1】:

我发现DefinitelyTyped (Typescript) 文件通常有助于弄清楚发生了什么。据我所知:

  • The gulp.src function 将提供NodeJS.ReadWriteStream
  • The node.d.ts file 有点难以理解,但基本上所有 ...Streams 都有一个 pipe 方法,它接收一个流并返回一个相同/相似 (?) 类型。

所以基本上,您返回gulp.src 的结果(管道位不会改变返回值的类型),它是一个节点 流。

这基本上意味着您可以运行serverweb 任务,并仅在它们成功完成后使用finish callbacks of the streams those tasks return 采取行动。

作为脚注,虽然我不熟悉确切的工作原理,但如果您需要等待多个流完成,我认为merge-stream 也可能会有所帮助。


这是一个基本示例(基于您的代码,减去 try..catch 位):

var gulp = require("gulp");
var mergeStream = require("merge-stream");

const build = {
  server: () => {
    process.stdout.write("MYMESSAGE: Server...\n");
    return gulp.src("src/nonexistent/server.js").pipe(gulp.dest("./build/server"));
  },
  web: () => {
    process.stdout.write("MYMESSAGE: Web...\n");
    return gulp.src("src/web.js").pipe(gulp.dest("./build/server"));
  }
}

gulp.task("serve", () => {
  const start = () => process.stdout.write("MYMESSAGE: Starting!\n");

  try {
    throw new Error("Simulated error!");
  } catch(err) {
    // In parallel build server and web, afterwards run
    // server iff there were no erros.
    mergeStream(build.server(), build.web())
      .on("error", () => console.error(err))
      .on("finish", () => start());    
  }
});

【讨论】:

  • 太棒了。我实际上在项目的其他地方使用了一些打字稿,我什至没有考虑过使用 .d.ts 来解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-13
  • 2013-06-13
  • 2014-08-05
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多