TypeStrong / fork-ts-checker-webpack-plugin

Webpack plugin that runs typescript type checker on a separate process.
MIT License
1.96k stars 239 forks source link

Type check only bundled files #714

Closed watjurk closed 2 years ago

watjurk commented 2 years ago

Current behavior

This plugin type-checks whole directory, it doesn't matter if the file is included in webpack bundle or not.

Expected behavior

For this plugin to type-check only files that are included in webpack bundle.

Steps to reproduce the issue

  1. Run your project that has no type errors (and is using fork-ts-checker-webpack-plugin)
  2. Create test.ts file in your's src, do not include this file in any other file, just create it like it's a ghost
  3. Create some type error in test.ts
  4. fork-ts-checker-webpack-plugin reports type-error from test.ts even though test.ts is not included in webpack bundle

Issue reproduction repository

https://github.com/watjurk/fork-ts-checker-webpack-plugin-issue

piotr-oles commented 2 years ago

It's the intended behavior of the plugin :) The plugin doesn't wait for webpack to resolve the dependency graph - it runs type-check immediately. This turns out to be faster in most cases because most of the time files inside your "src" directory are ~ of the dependency graph. And this is also consistent with how tsc works.

It's described in the README: https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#modules-resolution :)

watjurk commented 2 years ago

This sounds logical, but ts-loader actually does it in slightly different way - the webpack's way, and unfortunately my project was dependent on the way that ts-loader handled type checking, and I wanted to switch over to fork-ts. Are you able to create an option so that this plugin will handle type checking as described in the issue? Or this would be very difficult?

Thanks!

piotr-oles commented 2 years ago

I think it's possible to accomplish with existing hooks that this plugin provides :) Here is a plugin that I tested locally and it seems to work:

// webpack/OnlyWebpackErrorsInForkTsCheckerWebpackPlugin.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

module.exports = class OnlyWebpackErrorsInForkTsCheckerWebpackPlugin {
  apply(compiler) {
    const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);

    hooks.issues.tap('OnlyWebpackErrorsInForkTsCheckerWebpackPlugin', (issues, compilation) => {
      const files = new Set();
      for (const module of compilation.modules) {
        if (module.resource) {
          files.add(module.resource);
        }
      }
      // display errors only for files that are managed by webpack
      return issues.filter(issue => !issue.file || files.has(issue.file));
    });
  }
}

and then in the webpack.config.js:

// webpack.config.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const OnlyWebpackErrorsInForkTsCheckerWebpackPlugin = require('./webpack/OnlyWebpackErrorsInForkTsCheckerWebpackPlugin');

module.exports = {
  ...
  plugins: [
    new ForkTsCheckerWebpackPlugin(),
    new OnlyWebpackErrorsInForkTsCheckerWebpackPlugin()
  ]
};

The plugin will still run type-check on all files, but they will be ignored

piotr-oles commented 2 years ago

It works on Mac, I'm not sure if this will work on Windows due to path differences :)

watjurk commented 2 years ago

Thanks a lot it work like a dream!

Dzięki wielkie, działa jak marzenie! Kraków rządzi!