Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webpack watch compiles every file

According to the webpack documentation for watches

webpack can watch files and recompile whenever they change.

In my understanding, this means, that webpack will only compile the changed files.

I have a webpack.config.js that looks like this

module.exports = {
    watch: true,
    watchOptions: {
        ignored: /node_modules/,
    },
    entry: {
        "first": './web/assets/js/first.tsx',
        "second": './web/assets/js/second.tsx',
    },
    // other stuff
}

Now, when running ./node_modules/.bin/webpack the output log makes it look like ALL files are compiled

Webpack is watching the files…

Hash: d0ac7b9d70b906068f77
Version: webpack 4.3.0
Time: 10462ms
Built at: 3/29/2018 11:50:43 AM
              Asset       Size  Chunks             Chunk Names
    first.js    234 KiB       0  [emitted]  first
second.js  739 bytes       1  [emitted]  second
Entrypoint second = second.js
Entrypoint first = first.js
  [13] ../locale-data/index.js (ignored) 15 bytes {0} [built]
  [14] ./web/assets/js/react/component/First/First.tsx 1.05 KiB {0} [built]
  [15] ./web/assets/js/translations/tr.ts 4.83 KiB {0} [built]
  [16] ./web/assets/js/translations/it.ts 4.64 KiB {0} [built]
  [17] ./web/assets/js/translations/fr.ts 4.78 KiB {0} [built]
  [18] ./web/assets/js/translations/en.ts 4.31 KiB {0} [built]
  [19] ./web/assets/js/translations/de.ts 4.67 KiB {0} [built]
  [31] ./lib/locales (ignored) 15 bytes {0} [built]
  [37] ./lib/locales (ignored) 15 bytes {0} [built]
  [57] ./web/assets/js/first.tsx 559 bytes {0} [built]
  [58] ./web/assets/js/second.tsx 350 bytes {1} [built]
    + 48 hidden modules

When I now change something in first.tsx the output is the same. This looks to me like EVERY file is recompiled, but I only want the entry that has been changed to be recompiled. Am I missing something here or misunderstanding something?

My goal is to only recompile the files that have been changed which should be the way webpack watch works IMO.

Update: For further proof, I deleted both compiled files, changed a line in one entry point and the watcher still compiled both.

Update2: Here are some steps to reproduce

Steps to reproduce: These steps assume you already have yarn/npm installed.

  • Check out the repository I created which you can find at https://github.com/tzfrs/webpack-watch-bug
  • Initially run yarn install or npm install.
  • Run ./node_modules/.bin/webpack. This should create two files in the dist folder and automatically watch.
  • Delete dist/second.js
  • Change something in src/first.js
  • src/second.js has no changes, but will still be recompiled (because dist/second.js is created again).
like image 220
Musterknabe Avatar asked Mar 29 '18 09:03

Musterknabe


1 Answers

Webpack and similar watchers hold your entire bundle in memory, and watch a file stream. You can think of it kinda like an asynchronous reduce. Each time data is pushed to the stream, it updates the accumulated bundle accordingly, until the stream closes and the task ends.

If it has an out directory, it writes the latest state of the bundle -- that is, the entire bundle -- to that directory on each change. But even though we think of this as the primary goal, it's more like a "side effect" if we go with the reduce analogy.

This does not mean that it recompiled everything...in fact, unexpected changes like an unsafe deletion can actually break the watcher, precisely because it's not starting from scratch every time something changes.

For a demonstration, clone a larger project and notice the difference between the first compile (whole bundle) and subsequent (single file) updates. There should be an order of magnitude difference in time taken.

like image 66
Nathan Christie Avatar answered Sep 17 '22 21:09

Nathan Christie