levp / wrapper-webpack-plugin

A webpack plugin that wraps output files (chunks) with custom text or code.
91 stars 37 forks source link

All output files register changes with any file change while watching #7

Open jacksonStone opened 4 years ago

jacksonStone commented 4 years ago

When we use this plugin while running a webpack watch, with many output/entry files, all of these files are registering changes if any file has a change. Since most of the file source is cached for rebuilding the output files, output file construction does not seem to take long, but with sourcemaps enabled, all sourcemaps are also rebuilding, taking a lot of time.

This amounts to a watcher change taking close to the same amount of time as a whole webpack build for us.

Do you think there would be any way to add watcher support for this plugin such that it does not trigger changes to everything?

I've been poking around to see what's possible using the source of this project, but it seems if I check the chunk hash for changes and only run your logic on these, all the wrappers for other output files are removed.

Perhaps there is a different event hook that could be tapped into?

levp commented 4 years ago

@jacksonStone You're right, it does seem like the current implementation of this plugin causes all bundles to be rebuilt even when a change only affects one of them.

After some playing around it seems like the implementation should ignore chunks that have their rendered property set to true. I've tested the fix to the best of my abilities and currently marked it as 2.2.0-beta.0. Please let me know if this solves the issue and I'll mark it as a stable release.

npm i -D wrapper-webpack-plugin@2.2.0-beta.0

jacksonStone commented 4 years ago

Had a chance to give it a whirl. It seems to only rebuild the source file that had changes, however, all source files not built have the wrapper removed, and all sourcemaps are still being constructed.

marcins commented 4 years ago

Just ran into this as well, however I have some more input - Webpack's emit code keeps a cache based on the Source object identity rather than content:

https://github.com/webpack/webpack/blob/542ffa969d2f4c67c309ff711ccf00b27ace9ee5/lib/Compiler.js#L546-L554

This plugin creates a new Source object every time here: https://github.com/levp/wrapper-webpack-plugin/blob/e1809b10af71ffba82e4261a357a28b0b04e2355/wrapper-webpack-plugin.js#L51-L55 which means that cache is never valid on subsequent passes.

I haven't looked too deeply into it yet, but adding a cache to the plugin instance using the header/footer + original source object as a key, and returning the previous object if there's a match should avoid these re-emits.

(For reference - for our very large web application re-emit on a no-op change to a source file takes about 10s in watch mode, so cutting this down would be a significant win for us)