Macil / browserify-hmr

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

Does not work with multiple bundles #12

Open Gozala opened 8 years ago

Gozala commented 8 years ago

In my use case my application code consists of multiple bundles, for simplicity let's say two one for code running in main thread and other for web-worker thread. Each is bundled with a separate browserify + watchify bundle and both use hmr plugin for hot reloading.

As far as I can understand from error messages below second bundle is attempting to start a second hmr server which errors:

[12:36:02] Requiring external module babel-core/register
[12:36:04] Using gulpfile ~/Projects/browser.html/gulpfile.babel.js
[12:36:04] Starting 'hotreload'...
[12:36:04] Finished 'hotreload' after 426 μs
[12:36:04] Starting 'develop'...
[12:36:04] Starting 'watcher'...
[12:36:04] Finished 'watcher' after 15 μs
[12:36:04] Starting 'browser/index'...
[12:36:04] Begin bundling: 'browser/index'
[12:36:04] Starting 'service/history-worker'...
[12:36:04] Begin bundling: 'service/history-worker'
[12:36:04] Starting 'about/settings/index'...
[12:36:04] Begin bundling: 'about/settings/index'
12:36:21 GMT-0700 (PDT) [HMR] Emitting updates
12:36:21 GMT-0700 (PDT) [HMR] Listening on localhost:3123
[12:36:23] Completed bundling: 'service/history-worker'
[12:36:23] Finished 'service/history-worker' after 19 s
12:36:24 GMT-0700 (PDT) [HMR] Emitting updates
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: listen EADDRINUSE 127.0.0.1:3123
    at Object.exports._errnoException (util.js:874:11)
    at exports._exceptionWithHostPort (util.js:897:20)
    at Server._listen2 (net.js:1234:14)
    at listen (net.js:1270:10)
    at net.js:1379:9
    at GetAddrInfoReqWrap.asyncCallback [as callback] (dns.js:63:16)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:82:10)
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: Browserify-HMR lost connection to socket server
    at ChildProcess.<anonymous> (/Users/gozala/Projects/browser.html/node_modules/browserify-hmr/index.js:111:24)
    at emitNone (events.js:67:13)
    at ChildProcess.emit (events.js:166:7)
    at finish (internal/child_process.js:657:14)
    at doNTCallback0 (node.js:417:9)
    at process._tickCallback (node.js:346:13)

It would be nice if somehow multiple bundles could share same HMR instance. I also tried documented key parameter but that seems to fail due to #11 although not sure if that is what's it intended for.

Use of different port and url options per bundle works although I don't find it to be an ideal.

Macil commented 8 years ago

As per #11, this should work if you use the --url and --port options together. Please let me know if that doesn't seem to be the case or if you have any other trouble!

Gozala commented 8 years ago

@AgentME well the problem is that multiple web socket servers are started with the same port and the second one obviously fails. I do not see how --url or --port options would resolve this.

Macil commented 8 years ago

Oh, you want multiple bundles hosted from the same port. Sorry, I mixed this issue up with #11 a bit.

Each is bundled with a separate browserify + watchify bundle and both use hmr plugin for hot reloading.

Note that this could only work if both browserify builds were running in the same process. Making multiple builds rely on shared process state (the same socket server) bothers me a bit (if you tried to run each of the builds separately instead of all together in the same process, then it would fail as each tried to start a socket server on the same port). But then I do eventually want to make a production-friendly implementation of the socket server, and having virtual hosts -like functionality where one server can answer for multiple bundles does seem necessary for that.

I'll make the key option do what you expected and allow multiple bundles to be served from the same socket server.

Hebilicious commented 8 years ago

Any update on this ? Most wanted feature ! :)

Hebilicious commented 8 years ago

Hello @JulesWang , I'm gonna try your version and I'll let you know!

scottbedard commented 8 years ago

Has any progress been made on multiple bundle support?

w0bbes commented 8 years ago

Hey @scottbedard, wondering the same here... But i guess not.

So far i've solved it by letting all my instances use the 'main' socket. So none of them will serve their own socket, just listening to the main one.

So the ones listening on the main will get: watchify -vd -p [ browserify-hmr --noServe true -p 8888 -u localhost:8888] -e main.js -o bundle.js

And the main one will get: watchify -vd -p [ browserify-hmr -p 8888 -u localhost:8888 ] -e main.js -o bundle.js

Notice the --noServe while still added the port and url of the main socket.

Hope this helps, abit

scottbedard commented 8 years ago

@w0bbes Nice, that's an interesting solution. I ended up just switching to webpack, it makes more sense for my project anyway.

Macil commented 8 years ago

This hasn't been worked on yet. Being able to host multiple from the same port would be a neat feature, but I think some of the demand for the feature is misplaced. You can build different bundles with different instances of browserify-hmr running on different ports right now.

kentor commented 7 years ago

Yep we are running 4 instances of watchify with browserify-hmr in parallel, each with a different port for 4 different apps. Would be nice if they could all listen to the same hmr server, especially when adding another bundle, then I wouldn't have to launch another hmr server

ChuanyuWang commented 6 years ago

Yep, Most wanted feature, seems still no progress~