fork-ts-checker-webpack-plugin: Slow Performance on Incremental Runs (Project References)

Current behavior

Incremental typechecks are very slow.

We have a project that leverages Project References in Typescript. As the latest release of your plugin supports references we tried to upgrade. We are seeing an unusable drop in performance when type-checking this code.

image

For comparison, here is the same code change ran with tsc --build --incremental

image

Here is our config:

      new ForkTsCheckerWebpackPlugin({
        async: true,
        typescript: {
          mode: 'write-references',
          configFile: path.resolve(APP_ROOT, 'tsconfig.json'),
          configOverwrite: {
            compilerOptions: {
              incremental: true
            }
          },
          profile: true,
          build: true
        }
      }),

Expected behavior

Incremental typechecks should be quick.

Environment

  • fork-ts-checker-webpack-plugin: 5.0.0
  • typescript: 3.7.2
  • eslint: n/a
  • webpack: 4.39.3
  • os: macos

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 32 (2 by maintainers)

Most upvoted comments

Is it possible that this issue is back? I’m using Typescript 4.4.2 and after introducing a change in a package that is listed in the project tsconfig.json references my webpack-dev-server is incredibly slow (it recompiles couple of times before serving the newest files in the browser). This is my ForkTsCheckerWebpackPlugin setup:

new ForkTsCheckerWebpackPlugin({
      async: isEnvDevelopment,
      typescript: {
        configOverwrite: {
          compilerOptions: {
            sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
            skipLibCheck: true,
            inlineSourceMap: false,
            declarationMap: false,
            noEmit: true,
            incremental: true,
            tsBuildInfoFile: paths.appTsBuildInfoFile,
          },
        },
        context: paths.appPath,
        diagnosticOptions: {
          syntactic: true,
        },
        mode: 'write-references',
        build: true,
        profile: true,
      },
      issue: {
        // This one is specifically to match during CI tests,
        // as micromatch doesn't match
        // '../cra-template-typescript/template/src/App.tsx'
        // otherwise.
        include: [{ file: '../**/src/**/*.{ts,tsx}' }, { file: '**/src/**/*.{ts,tsx}' }],
        exclude: [
          { file: '**/src/**/__tests__/**' },
          { file: '**/src/**/?(*.){spec}.*' },
          { file: '**/src/**/?(*.){stories}.*' },
          { file: '**/src/setup-tests.*' },
        ],
      },
      logger: {
        infrastructure: 'silent',
      },
    }),

I’m using "fork-ts-checker-webpack-plugin": "6.3.3", version. My project is an ejected create-react-app with some updates to support webpack 5.

I’ve added support for a “generateTrace” option available in typescript 4.1.0-beta in 6.0.0-alpha.2. It should help to debug performance issues 😃

https://github.com/nathanforce/monorepo-ts-projects-webpack

@piotr-oles Here’s my best attempt. It is very simplistic but follows the same structure/patterns as the real repo, just with far less files. Even in this tiny example I am seeing slower numbers on the webpack side when running the two commands:

webpack:

npx webpack-dev-server --mode=development --config ./apps/alpha/webpack.config.js

tsc:

npx tsc --build ./apps/alpha/tsconfig.json --extendedDiagnostics --incremental --watch

As is expected in such a contrived reproduction, the differences here are much much smaller but maybe it can help you spot something. Sorry for the delay!

Cheers

As a profile I mean basically debugging/finding the root cause of this behaviour using whatever method you like. It will require digging into typescript’s codebase which can be a time-consuming task 😃

* The first time during the compilation phase (via babel), where TSC actually transpiles the code, outputting JS code

Just FYI: babel is not running tsc, but just stripping away type information, so when you start debugging in the typescript compiler, this step will never hit anything there.