Macil / browserify-hmr

Hot Module Replacement plugin for Browserify
MIT License
373 stars 26 forks source link

Modules get updated before bundle completes rebuild #13

Closed scottcorgan closed 8 years ago

scottcorgan commented 8 years ago

I have a fairly large codebase that seems to produce a race condition between browserify-hmr and watchify. Sometimes the build takes about 8 seconds to rebuild when I file changes, but the module will hot (re)load after only a second.

I'm not sure if the race condition is caused me, or if it's actually a bug in browserify-hmr.

Script

{
  "scripts": {
    "watch:js": "NODE_ENV=development watchify -t babelify -t envify -p browserify-hmr --extension=.jsx -vd $npm_package_config_entry -o $npm_package_config_output"
  }
}

Video of Code Being Saved Running

browserify-hmr-bug

Macil commented 8 years ago

This is a feature! I regularly use Browserify-hmr with large codebases and what you're seeing is intended. Let me know if it doesn't seem to be actually emitting the correct changes.

Browserify goes through several steps where files are gathered, individually transformed, and then bundled together. The last seems to take the longest, but it's not necessary for Browserify-hmr. Browserify-hmr causes Browserify to prioritize finishing the second step before beginning the third step, and it's able to emit updates to clients as soon as the second step is done. (There is a small issue that if emitting your first change takes 1 second and your rebuild takes 8 seconds, and you make two changes two seconds apart, then your first change will be emitted after a second, but your second change will be delayed much further because it's blocked by the full bundle step that's still happening for the first change. I don't have a good idea yet about how to address this. It might require an analog to webpack-dev-server to be made.)

scottcorgan commented 8 years ago

hmr works great on components that are either top level, or one deep. But, past that, the updates get pushed before the bundle actually updates, so the modules never update in the browser.

The updates never happen if the file is associated with many other files and the bundle takes a bit longer to complete.

Macil commented 8 years ago

Browserify-hmr doesn't use the output bundle at all for delivering updates in the default websocket mode. It's not read. Browserify-hmr can emit updates as soon as browserify has processed the changed files, before it has re-bundled everything.

scottcorgan commented 8 years ago

One more question. Is there a reason that source maps are required. If I turn them off, hmr doesn't work. The Webpack hmr doesn't require this so I was curious as to why browserify-hmr does.

Macil commented 8 years ago

Hm, sourcemaps aren't intended to be required. (There is issue #9 about browserify-hmr failing on invalid sourcemaps, but missing sourcemaps have been fine as far as I've seen.) Can you open a new issue with an example that can be used to reproduce the error?