wasm-pack-plugin icon indicating copy to clipboard operation
wasm-pack-plugin copied to clipboard

The bundle is not recreated by webpack after source files change.

Open chmnchiang opened this issue 3 years ago • 4 comments

🐛 Bug description

The browser failed to reload after changing the source when using this plugin with webpack-dev-server. This only happens when using wasm-pack with version 0.10.x, but not 0.9.x (and the version of wasm-pack-plugin does not seems to affect the bug). See https://github.com/rustwasm/rust-webpack-template/issues/180.

🤔 Expected Behavior

When using webpack-dev-server with wasm-pack-plugin, after the source files change and wasm-pack recompiled the wasm file, the bundle should be recreated and the browser should reload.

👟 Steps to reproduce

  1. In any directory, run npm init rust-webpack my-app to clone the template.
  2. cd my-app and then npm start to start the dev server.
  3. Edit src/lib.rs, for example, duplicate the line console::log_1(...). The browser will reload and we could see Hello world! get print twice in the console.
  4. Edit src/lib.rs, for example, duplicate the line console::log_1(...) again.
  5. The command line output of npm start does not show the wasm file being rebundled and the browser does not reload.
  6. Add wasm-pack: "0.9.1" in depDependencies in the package.json and webpack starts to reload browser when source files change.

🌍 Your environment

wasm-pack version: wasm-pack 0.10.2 rustc version: rustc 1.56.1 (59eed8a2a 2021-11-01)

chmnchiang avatar Jan 04 '22 03:01 chmnchiang

Can you try to add this ↓ too Webpack config? Will you check to see if that helps solve the problem?

watchOptions: {
   aggregateTimeout: 200,
   poll: 200,
},

I had the same problem. After investigating it, it turned out that webpack does not correctly detect changes when files in the pkg folder are created and deleted. If you add timeout, it works correctly.

I haven't figured out exactly where the problem is, but it seems to be in the watchpack library. The code there is very tricky.

SonyStone avatar Jan 04 '22 10:01 SonyStone

i can confirm webpack v5 dev server doesn't notice changes after rebuild by wasm-pack v0.10.2
downgrading wasm-pack to v0.9.1 indeed fixes the issue.

using webpack's polling watch option fixes it for me too.

art-in avatar Jan 11 '22 19:01 art-in

@SonyStone I can confirm that adding the config you mention solve the problem for me. Thank you!

chmnchiang avatar Jan 12 '22 06:01 chmnchiang

I was able to trace it a little further.

It seems that watchpack is receiving a "rename" event for the files wasm-pack creates.

This rename event is handled by: https://github.com/webpack/watchpack/blob/15ac38f884103dbf19ef4fb816c2a00fab481027/lib/watchEventSource.js#L45

And later: https://github.com/webpack/watchpack/blob/15ac38f884103dbf19ef4fb816c2a00fab481027/lib/DirectoryWatcher.js#L422

This setMissing call will basically remove the files from the watch list.

And I believe that this is the reason it works well for the first 2 builds, as noted here: https://github.com/rustwasm/rust-webpack-template/issues/180 During the first build, watchpack puts the watchers in place. During the second build, all watchers will be removed, as watchpack believes all files were renamed. For the following builds, all files generated by wasm-pack will be ignored.

If wasm-packcreates fresh files (instead of replacing existing ones), then another event is triggered (the "changed" event), and watchpack handles it well.

I believe this is most likely a watchpack issue. Or maybe, wasm-pack is creating files in an "esoteric" way.

A workaround I am using is to clean the pkg directory before build:

cargo watch -i "pkg/*" -s "rm -rf pkg && wasm-pack build -d pkg"

Also webpack.config.js:

watchOptions: {
   aggregateTimeout: 500
   // poll: 200, is not necessary as long as you remove pkg/* before building your wasm files
}

yokomizor avatar Jan 25 '22 02:01 yokomizor