有条件地调用GulpJS任务(手动)

时间:2016-01-31 06:41:07

标签: javascript node.js asynchronous gulp

我想构建一个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是异步运行这些操作的吗?
  • 假设异步操作;我怎么能等待这些完成呢?
  • 如果不是异步,我该如何执行它们?

1 个答案:

答案 0 :(得分:1)

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

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

因此,基本上,您返回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());    
  }
});