gulp-typescript: Very slow incremental compilation (2.6x slower) compared to tsc

With “gulp-typescript”: “3.2.3”,

Expected behavior:

Should be as fast as tsc -w

Synchronizing program
Files:           289
Lines:        121510
Nodes:        524773
Identifiers:  184342
Symbols:      244975
Types:         51810
Memory used: 263018K
I/O read:      0.03s
I/O write:     0.09s
Parse time:    2.55s
Bind time:     0.63s
Check time:    4.13s
Emit time:     2.57s
Total time:    9.87s
9:21:12 PM - Compilation complete. Watching for file changes.

9:21:20 PM - File change detected. Starting incremental compilation...
Synchronizing program
...
Total time:    3.34s
9:21:23 PM - Compilation complete. Watching for file changes.
9:21:29 PM - File change detected. Starting incremental compilation...
Synchronizing program
...
Total time:    2.81s

Actual behavior:

Very slow, gulp does:

[21:17:49] Finished 'compileSources' after 9.31 s
... change a file ...
[21:18:04] Finished 'compileSources' after 7.4 s

Your gulpfile:

const ts = require('gulp-typescript');
const tsProject = ts.createProject('tsconfig.json');
gulp.task('compileSources', () =>
  tsProject.src()
      .pipe(tsProject())
      .js.pipe(gulp.dest('artifacts'))
);

tsconfig.json

Include your tsconfig, if related to this issue.

{
    "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "allowJs": true,
        "jsx": "react",
        "moduleResolution": "node",
        "importHelpers": true,
        "outDir": "artifacts",
        "rootDir": ".",
        "rootDirs": [
            "src",
            "node_modules/include-common"
        ],
        "sourceMap": true,
        "noImplicitAny": true,
        "suppressImplicitAnyIndexErrors": true,
        "strictNullChecks": true,
        "lib": ["dom", "es2017", "es2016", "es2015"],
        "baseUrl": ".",
        "paths": {
            "escodegen": ["node_modules/escodegen"],
            "esprima": ["node_modules/esprima"],
            "esquery": ["node_modules/esquery"],
            "firebase": ["node_modules/firebase"],
            "firebase-admin": ["node_modules/firebase-admin"],
            "firebase-safekey": ["node_modules/firebase-safekey"],
            "include-common/*": ["node_modules/include-common/*"]
        },
        "skipLibCheck": true,
        "types": [
            "color",
            "d3-format",
            "d3-scale",
            "esprima",
            "estree",
            "react",
            "react-native",
            "react-native-fs",
            "react-navigation",
            "react-redux",
            "redux-actions"
        ]
    },
    "compileOnSave": false,
    "include": [
        "ourTypings/**/*.d.ts",
        "src/**/*.ts",
        "src/**/*.tsx",
        "node_modules/include-common/**/*.ts",
        "node_modules/include-common/**/*.tsx"
    ],
    "exclude": [
        "android",
        "artifacts",
        "gruntfile.js",
        "node_modules/include-common/artifacts",
        "node_modules/include-common/node_modules"
    ]
}

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 3
  • Comments: 29 (8 by maintainers)

Most upvoted comments

That completes in 100ms for me. Testing it looks like tsc 2.7.2 takes the same amount of time (if not longer) on the first compile, and then is nearly instant for later compiles. It’s a lot more than 2.6x now, close to 100x faster (0.07 seconds vs 6.6 seconds). gulp-typescript seems to always take 6-8 seconds.

Looking at the diagnostics difference I think tsc is not reloading all the types for each incremental compile (57770 for first compile, 238 for second, see below) while gulp-typescript is.

gulpfile.js

const gulp = require('gulp');
const { spawn } = require('child_process');
const ts = require('gulp-typescript');

const tsProject = ts.createProject('./tsconfig.json');

gulp.task('compileWithGulpTypeScript', () => {
  const t1 = Date.now();
  const src = tsProject.src();
  console.log('.src()', Date.now() - t1);
  const t2 = Date.now();
  const transformer = tsProject();
  console.log('transformer', Date.now() - t2);
  return src
    .pipe(transformer)
    .pipe(gulp.dest('artifacts'));
});

gulp.task('compileWithGulpTypeScript-watch', () => {
  gulp.watch(['src/**/*.ts'], ['compileWithGulpTypeScript'])
});

gulp.task('watchSources', () => {
    // tsc --watch clears the shell, so we use a gross hack around it.
    // https://github.com/Microsoft/TypeScript/issues/21295#issuecomment-367571059
    spawn(`tsc -w | awk '{ gsub(/\\033c/, "") system("")}1'`, {
        stdio: 'inherit',
        shell: true,
    });
});

Output from gulp-typescript

$ gulp compileWithGulpTypeScript-watch
[13:00:00] Using gulpfile /Checkouts/grasshopper/packages/app/gulpfile.js
[13:00:00] Starting 'compileWithGulpTypeScript-watch'...
[13:00:00] Finished 'compileWithGulpTypeScript-watch' after 79 ms
[13:00:59] Starting 'compileWithGulpTypeScript'...
.src() 135
transformer 0
[13:01:09] Finished 'compileWithGulpTypeScript' after 9.27 s
[13:01:11] Starting 'compileWithGulpTypeScript'...
.src() 100
transformer 0
[13:01:18] Finished 'compileWithGulpTypeScript' after 7.28 s
[13:01:21] Starting 'compileWithGulpTypeScript'...
.src() 87
transformer 0
[13:01:28] Finished 'compileWithGulpTypeScript' after 6.71 s
[13:01:46] Starting 'compileWithGulpTypeScript'...
.src() 101
transformer 0
[13:01:53] Finished 'compileWithGulpTypeScript' after 6.64 s

Output from tsc

$ tsc -v
Version 2.7.2
$ gulp watchSources
[13:02:41] Using gulpfile /Checkouts/grasshopper/packages/app/gulpfile.js
[13:02:41] Starting 'watchSources'...
[13:02:41] Finished 'watchSources' after 3.8 ms
13:02:42 - Starting compilation in watch mode...
13:02:52 - Compilation complete. Watching for file changes.
13:02:59 - File change detected. Starting incremental compilation...
13:02:59 - Compilation complete. Watching for file changes.
13:03:05 - File change detected. Starting incremental compilation...
13:03:05 - Compilation complete. Watching for file changes.
13:03:14 - File change detected. Starting incremental compilation...
13:03:14 - Compilation complete. Watching for file changes.
13:03:17 - File change detected. Starting incremental compilation...
13:03:17 - Compilation complete. Watching for file changes.

tsc with --diagnostics turned on

$ gulp watchSources
[13:08:24] Using gulpfile /Checkouts/grasshopper/packages/app/gulpfile.js
[13:08:24] Starting 'watchSources'...
[13:08:24] Finished 'watchSources' after 4.03 ms
13:08:24 - Starting compilation in watch mode...

Synchronizing program
Files:           367
Lines:        161504
Nodes:        628499
Identifiers:  217633
Symbols:      276782
Types:         57770
Memory used: 296777K
I/O read:      0.05s
I/O write:     0.18s
Parse time:    2.68s
Bind time:     0.86s
Check time:    4.35s
Emit time:     2.93s
Total time:   10.82s
13:08:35 - Compilation complete. Watching for file changes.

13:08:43 - File change detected. Starting incremental compilation...

Synchronizing program
Files:           367
Lines:        161504
Nodes:        628499
Identifiers:  217633
Symbols:      129934
Types:           238
Memory used: 238081K
I/O read:      0.00s
I/O write:     0.00s
Parse time:    0.01s
Bind time:     0.00s
Check time:    0.04s
Emit time:     0.01s
Total time:    0.07s
13:08:43 - Compilation complete. Watching for file changes.

I’ve posted an answer on your StackOverflow question, let me know if anything is unclear.

@ivogabe I tried the alpha.1, unfortunately the results are the same (even worse in most cases). Previous build during watch (when saving a file, without modifying its content) was taking ~10 seconds, it’s taking up twice as long with the alpha.

@marcghorayeb I don’t. I keep tsc running and rerun gulp whenever I want to publish/start the application.