Anders Liu Anders Liu - 3 months ago 16
TypeScript Question

Gulp task finished before the output files are generated

---- Updates on top ------

Some friends point out that I should return the stream from the task. That's right but doesn't help.

In fact, in my first version, I returned the stream, the

var rs
parts once were
return
.

The problem is, the compiled js files are generated after the task has completed. So no matter I use the
done
callback, or return the stream from task, the task has really completed, and the next task is started, but the generated files are not ready.

---- Here's the original question ----

I've a gulpfile.js to firstly compile a bunch of .ts file into js, and then pack the output js files throught webpack. Here're the important parts of my gulpfile.js:

const gulp = require("gulp");
const ts = require("gulp-typescript");
const webpack = require("webpack-stream");

gulp.task("default", ["build"]);
gulp.task("build", ["compile", "pack"]);
gulp.task("compile", task_compile);
gulp.task("pack", ["compile"], task_pack);

function task_compile(done) {
return util_compile_ts("main", done);
}

function task_pack(done) {
return util_pack_js("main", done);
}

function util_compile_ts(proj, done) {
const dirSrc = "src/" + proj;
const dirCompiled = "out/compiled/" + proj;
const dirBuilt = "out/built";

var tscfg = require("./" + dirSrc + "/tsconfig.json").compilerOptions;
var rs = gulp
.src(dirSrc + "/**/*.ts")
.pipe(ts(tscfg))
.pipe(gulp.dest(dirCompiled))
.on("end", done);
}

function util_pack_js(proj, done) {
const dirSrc = "src/" + proj;
const dirCompiled = "out/compiled/" + proj;
const dirBuilt = "out/built";

var wpcfg = require("./" + dirSrc + "/webpack.config.js");
wpcfg.context = path.resolve(dirSrc, wpcfg.context)
wpcfg.output.path = path.resolve(dirSrc, wpcfg.output.path)
var rs = gulp
.src(dirCompiled + "/**/*.js")
.pipe(webpack(wpcfg))
.pipe(gulp.dest(dirBuilt))
.on("end", done);
}


If I run
gulp compile
and then
gulp pack
, no problem. But when I run just
gulp
, and error is occurs:

Error: Entry module not found: Error: Cannot resolve 'file' or 'directory'


And the path of compiled js files are listed, the path itself is okay, but hadn't be copied to the
compiled
folder.

I observed the process of ts compilation, and I found,
The ts task finished before the output files are actually generated. When run
gulp compile
, the gulp task showed finished and 1 or 2 seconds after, the generated files appeared in the
compiled
folder.

So when I run
gulp
, the
pack
task will start immediately after
compile
task finished, at that time, the js outputs are not ready on disk, so the
pack
task failed because it can't find input.

So question is, how could I wait the compiled js files are ready and proceed to the next task?




P.S. I don't want use setTimeout for a hard coded waiting....

Thanks,
Anders

Answer

As per the documentation for gulp-typescript the returned stream of ts is not your JavaScript files. It's a combination of .js and .d.ts. Referring to TypeScripts exampels see how they select the JavaScript files in the stream.

Try changing your stream flow by selecting the JavaScript files and further more return the stream to let gulp handle the done callback for you.

function util_compile_ts(proj, done) {
  const dirSrc = "src/" + proj;
  const dirCompiled = "out/compiled/" + proj;
  const dirBuilt = "out/built";

  var tscfg = require("./" + dirSrc + "/tsconfig.json").compilerOptions;
  return gulp
    .src(dirSrc + "/**/*.ts")
    .pipe(ts(tscfg))
    .js
    .pipe(gulp.dest(dirCompiled));
}
Comments