eslint-webpack-plugin icon indicating copy to clipboard operation
eslint-webpack-plugin copied to clipboard

lintDirtyModulesOnly relies on a populated cache, and lints all files if cache is not present

Open joshwilsonvu opened this issue 2 years ago • 2 comments
trafficstars

Bug report

Actual Behavior

I've run into a performance issue when using lintDirtyModulesOnly: true and cache: true on a large repository that I believe was caused by #197.

On the initial build, ESLint is not run on any files, as expected.

On the first rebuild, even of "leaf" files with few or no dependencies, all files are linted. This takes ~10 minutes on my repository due to the number of files and certain slow ESLint rules, assuming a cold cache.

On subsequent rebuilds, only changed files and files that depend on them are linted. The cache seems to be working properly.

Expected Behavior

On the first and all subsequent rebuilds, only changed files and files that depend on them should be linted. lintDirtyModulesOnly should not rely on the ESLint cache to be present and populated for its functionality to work.

How Do We Reproduce?

I've created a minimal reproduction of the issue here.

  • After running npm install, run npm start, and the dev server will run a build quickly. You'll see some debug output from slow-rebuild, showing which files would be linted if lintDirtyModulesOnly were not set to true; it comes from webpack.config.js where eslint-webpack-plugin's logic is reproduced to aid debugging.
  • Make a small change to one of the "leaf" files, e.g. src/a.js, such as adding a few newlines, and save the file. You'll see debug output from slow-rebuild showing that all files are to be linted, and output from eslint:* showing that ESLint is actually running on all files. This is what's slow for me and my team.
  • Make another small change to one of the "leaf" files, and save the file. You'll again see that all files are to be linted, but this time the ESLint cache kicks in, and only the changed file is linted again.
  • To try again, run npm run clean to clear the ESLint cache.

When the line compilation.hooks.stillValidModule.tap(this.key, addFile); in node_modules/eslint-webpack-plugin/dist/index.js is removed, the plugin no longer adds modules that didn't need to be rebuilt. This is demonstrated by commenting out the same line in the reproduction's webpack.config.js. Now, any rebuild only lints the files that actually changed, cache or no cache.

I recognize that the line was added to avoid an issue when using the persistent cache, but it seems like this was done on the assumption that lintDirtyModulesOnly is set to false. I suggest only tapping the stillValidModule hook if lintDirtyModulesOnly === false.

I can submit a pull request to make this change.

Please paste the results of npx webpack-cli info here, and mention other relevant information

  System:
    OS: macOS 11.7.4
    CPU: (8) x64 Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
    Memory: 1.37 GB / 32.00 GB
  Binaries:
    Node: 16.13.0 - ~/.nvm/versions/node/v16.13.0/bin/node
    Yarn: 1.22.17 - /usr/local/bin/yarn
    npm: 8.1.0 - ~/.nvm/versions/node/v16.13.0/bin/npm
  Browsers:
    Chrome: 111.0.5563.146
    Safari: 16.3
  Packages:
    eslint-webpack-plugin: ^4.0.0 => 4.0.0 
    webpack: ^5.77.0 => 5.77.0 
    webpack-cli: ^5.0.1 => 5.0.1 
    webpack-dev-server: ^4.13.2 => 4.13.2 

joshwilsonvu avatar Apr 03 '23 20:04 joshwilsonvu

+1. I also had this bug when I upgraded to version 4.0.0. (In version 4.0.1 too)

frolant avatar Apr 11 '23 05:04 frolant

Same problem as OP under similar circumstances, confirm still an issue. Based on the description i was hoping setting lintDirtyModulesOnly: false or cache: false would be temp fix. No dice.

If you reach this thread downgrade to 3.2.0 until a new version is published. Or look into other plugins, because this has been open too long. (we're volunteers! IDC.)

joshuambg avatar Jul 08 '23 01:07 joshuambg