Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use location.port when location.hostname is used to infer HMR socket URL #1664

Merged
merged 6 commits into from Mar 7, 2019

Conversation

rlamana
Copy link
Contributor

@rlamana rlamana commented Feb 13, 2019

  • This is a bugfix
  • This is a feature
  • This is a code refactor
  • This is a test update
  • This is a docs update
  • This is a metadata update

Motivation / Use-Case

On a externally exposed dev server (using host 0.0.0.0), HMR client code builds the socket URL using location.hostname but uses the port set in server's configuration. In a more complex and layered architecture, since the browser is at the very end of it, the proper way to infer socket's URL (as exposed and proxied by dev server in .../sockjs-node/info?t=XX) is to also use location.port along with the location.hostname.

More and more we see the scenario where the dev server is used in a cloud-based development environment or an architecture with some sort of proxy in front of it.

  • With a dev server externally exposed, host 0.0.0.0 and port 9000 and a proxy exposing it in http://dev.mydomain.com (default port 80).
    • Expected HMR socket generated URL: http://dev.mydomain.com/sockjs-node/info?t=XX (default port 80).
    • Actual HMR socket generated URL: http://dev.mydomain.com:9000/sockjs-node/info?t=XX (wrong port 9000).

More details in issue: #1663

Breaking Changes

No.
Those who exposed also that wrong port in their proxies as a way around the issue can now remove that configuration.

@rlamana rlamana changed the title Use location.port when location.hostname is used as a fallback in client Use location.port when location.hostname is used to infer HMR socket URL Feb 14, 2019
Copy link
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, please add tests

@rlamana
Copy link
Contributor Author

rlamana commented Feb 15, 2019

@evilebottnawi How are you testing the logic of the client code? I looked for it but couldn't find it in any of the tests. I guess webdriver is the right solution here but I didn't want to add too much overhead to your current tests. Guide me on how you recommend to do it and I'll be glad to add it.

@alexander-akait
Copy link
Member

@rlamana
Copy link
Contributor Author

rlamana commented Feb 20, 2019

@evilebottnawi as I understand those tests are checking that the socket and the server are available, but it is not testing the client code that will be executed on the browser's end (more precisely testing the code in https://github.com/webpack/webpack-dev-server/blob/master/client-src/default/index.js).

Any suggestions on how to test it without adding the overhead of webdriver?

https://github.com/webpack/webpack-dev-server/blob/master/test/Socket.test.js

@alexander-akait
Copy link
Member

/cc @rlamana oh, need thinks how we can tests client, maybe we need setup something to e2e testing
/cc @hiroppy What do you think?

@codecov
Copy link

codecov bot commented Feb 27, 2019

Codecov Report

Merging #1664 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #1664   +/-   ##
=======================================
  Coverage   83.76%   83.76%           
=======================================
  Files           8        8           
  Lines         536      536           
  Branches      161      161           
=======================================
  Hits          449      449           
  Misses         70       70           
  Partials       17       17

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update cb10f83...cf42f28. Read the comment docs.

@rlamana
Copy link
Contributor Author

rlamana commented Feb 27, 2019

@evilebottnawi @hiroppy I added some e2e tests using puppeteer headless Chrome API. This allows testing my fix and enables more e2e testing.

I created a new Client.test.js that contains this client code related tests: https://github.com/webpack/webpack-dev-server/blob/50ef125fbfe04eb51f6788a0c44ada539834ea57/test/Client.test.js

Also the runBrowser helper allows to quickly start the headless browser for e2e testing.

Let me know what you think.

@alexander-akait alexander-akait removed the request for review from michael-ciniawsky March 4, 2019 09:13
@alexander-akait
Copy link
Member

Looks good! Ready to merge?

@rlamana
Copy link
Contributor Author

rlamana commented Mar 4, 2019

@evilebottnawi it's ready but for some weird reason the test keeps failing in node 6. The proxy I use fails with a EADDRNOTAVAIL error. I've been trying to repro in a container with node 6.16.0 (same version Appveyor uses), but it works just fine and the test passes without problems. Any idea why this could be happening?

@alexander-akait
Copy link
Member

@rlamana

 console.info node_modules/http-proxy-middleware/lib/logger.js:77
      [HPM] Proxy created: /  ->  http://0.0.0.0:8080
    console.error node_modules/http-proxy-middleware/lib/logger.js:89
      [HPM] Error occurred while trying to proxy request /sockjs-node from localhost:9050 to http://0.0.0.0:8080 (EADDRNOTAVAIL) (https://nodejs.org/api/errors.html#errors_common_system_errors)
    console.error node_modules/http-proxy-middleware/lib/logger.js:89
      [HPM] Error occurred while trying to proxy request /main from localhost:9050 to http://0.0.0.0:8080 (EADDRNOTAVAIL) (https://nodejs.org/api/errors.html#errors_common_system_errors)
  ● Client code › behind a proxy › responds with a 200
    expected 200 "OK", got 500 "Internal Server Error"
      at Test.Object.<anonymous>.Test._assertStatus (node_modules/supertest/lib/test.js:268:12)
      at Test.Object.<anonymous>.Test._assertFunction (node_modules/supertest/lib/test.js:283:11)
      at Test.Object.<anonymous>.Test.assert (node_modules/supertest/lib/test.js:173:18)
      at localAssert (node_modules/supertest/lib/test.js:131:12)
      at node_modules/supertest/lib/test.js:128:5
      at Test.Object.<anonymous>.Request.callback (node_modules/superagent/lib/node/index.js:756:3)
      at IncomingMessage.parser (node_modules/superagent/lib/node/index.js:944:18)
  ● Client code › behind a proxy › requests websocket through the proxy with proper port number
    Timeout - Async callback was not invoked within the 30000ms timeout specified by jest.setTimeout.
      58 |     });
      59 | 
    > 60 |     it('requests websocket through the proxy with proper port number', (done) => {
         |     ^
      61 |       runBrowser().then(({ page, browser }) => {
      62 |         page
      63 |           .waitForRequest((requestObj) => requestObj.url().match(/sockjs-node/))
      at new Spec (node_modules/jest-jasmine2/build/jasmine/Spec.js:92:20)
      at Suite.it (test/Client.test.js:60:5)
      at Suite.describe (test/Client.test.js:42:3)
      at Object.describe (test/Client.test.js:24:1)

Maybe something doesn't handle (like errors) or something starts early then tests

@alexander-akait
Copy link
Member

Oh, no ideas
/cc @hiroppy

@alexander-akait
Copy link
Member

Something wrong with CI 😕

@rlamana
Copy link
Contributor Author

rlamana commented Mar 5, 2019

@evilebottnawi I'm still trying to figure out why the proxy fails to connect to the devserver on the appveyor Windows environment for node 6 when the host is 0.0.0.0. I tried to launch a local instance of the appveyor env in local to repro the issue and try to debug with no luck...

@rlamana
Copy link
Contributor Author

rlamana commented Mar 5, 2019

@evilebottnawi @hiroppy, it is now ready to merge.

Apparently, win32/node 6 has issues establishing a connection to 0.0.0.0. I fixed it by just pointing the test proxy to localhost. The test needs the dev server to be listening on 0.0.0.0, it doesn't really matter how the proxy redirects to it anyway, as long as it reaches the dev server.

With this PR you can now use the runBrowser helper I included to add more e2e testing. I hope this helps.

@hiroppy
Copy link
Member

hiroppy commented Mar 5, 2019

Sorry for the late reply. Thank you for creating e2e environment.
@rlamana Could you change the port number because 8080 is popular number?

@rlamana
Copy link
Contributor Author

rlamana commented Mar 5, 2019

@hiroppy in the test code? sure! I just thought since it should be in an isolated environment it wouldn't matter. I'll just set 9001 for the dev server and 9000 for the proxy.

Copy link
Member

@hiroppy hiroppy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if ci is green

@hiroppy
Copy link
Member

hiroppy commented Mar 6, 2019

/cc @evilebottnawi PTAL;)

poll: true,
},
};
addEntries(config, options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @rlamana Looks we catch bug, when we use API, hot plugin should be added too, can you create issue?

Copy link
Contributor Author

@rlamana rlamana Mar 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed that it was the API expected behavior, so I didn't think it was a bug. It all makes sense now. I will create the issue then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created issue #1703.

Copy link
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good work! Let's create issue about note above and we can merge

@alexander-akait alexander-akait merged commit 2f7f052 into webpack:master Mar 7, 2019
@pedrofurtado
Copy link

pedrofurtado commented Apr 8, 2019

@rlamana @evilebottnawi This PR, in version 3.3.0, breaks the use of webpack-dev-server with Rails webpacker gem, inside Docker containers. We used to configure rails app to execute in 0.0.0.0:3000 (from container "A"), and webpack-dev-server in 0.0.0.0:3035 (from container "B"). So, the socket URL must be "0.0.0.0:3035". But, with this version, the socket URL is generated as "0.0.0.0:3000" (same port of Rails app, instead of 3035).

@pedrofurtado
Copy link

The version 3.2.1 does not have problem with it 👍

@nick
Copy link

nick commented Apr 8, 2019

This change also broke my setup. I have a static assets server on port 3000 that refers to the webpack-dev-server build on port 8080. Now it is looking for the websocket on port 3000 instead of 8080. This worked fine in 3.2.1.

@rlamana
Copy link
Contributor Author

rlamana commented Apr 8, 2019

@pedrofurtado @nick, so as I understand you are not using the dev-server to actually serve your files, but just using it for the hot reload capability?

https://github.com/webpack-contrib/webpack-hot-middleware actually allows you to add hot reloading into an existing server.

@rlamana
Copy link
Contributor Author

rlamana commented Apr 8, 2019

I wonder if client-src/default/index.js should also take into account the devServer.public option to override the URL value and support these kind of scenarios where dev server is not use to serve the files.

@jcudzich
Copy link

jcudzich commented Apr 9, 2019

@rlamana This change also broke my setup. I using the dev-server the same way as @nick.

@chenyong
Copy link

chenyong commented Apr 9, 2019

This change broke our tools too. We have multiple sites proxied to a single domain with different paths. The old behavior was to get the port the actual Webpack dev server, rather than the one after proxied. Now the port changed and it's very tricky works to update the rest parts of the toolchains.

@pedrofurtado
Copy link

pedrofurtado commented Apr 9, 2019

@pedrofurtado @nick, so as I understand you are not using the dev-server to actually serve your files, but just using it for the hot reload capability?

https://github.com/webpack-contrib/webpack-hot-middleware actually allows you to add hot reloading into an existing server.

Thanks for feedback, @rlamana ! Firstly, thanks for you work in maintainance of webpack-dev-server!

Actually, I use webpack-dev-server for serve static files and hot replacement. For this, we here use the Webpacker gem (Integration between Webpack and Rails -> https://github.com/rails/webpacker ), that provides the two features mentioned (serving static files and hot replacement). Our setup is Rails application running in localhost:3000, and webpack-dev-server (and its socket) running in localhost:3035

My scenario and scenario of @nick are similar 👍

@alexander-akait
Copy link
Member

It was fixed, please test with latest version

@pedrofurtado
Copy link

@evilebottnawi Thanks! I will test here. Doubt: The latest version is the 3.3.0 (re-released) or the branch master?

@alexander-akait
Copy link
Member

@pedrofurtado 3.3.0, but we prepare 3.3.1 on today due some regressions

@pedrofurtado
Copy link

@evilebottnawi Ok, thank you!

@pedrofurtado
Copy link

pedrofurtado commented Apr 10, 2019

@evilebottnawi @rlamana Even in 3.3.1, the error is still occuring 😢 (as described in #1664 (comment) )

The workaround, for me, is to lock in version 3.2.1 for a while.

@hiroppy
Copy link
Member

hiroppy commented Apr 10, 2019

@pedrofurtado Please submit a reproducable repo.

@leoliu
Copy link

leoliu commented Apr 12, 2019

Broke my setup too (similar to #1664 (comment).). webpack-dev-server running on a different port is only used to serve assets i.e. js and whatnot.

@alexander-akait
Copy link
Member

#1664 (comment)

@timboslice69
Copy link

also broke my setup, this fix is a breaking change, maybe revisit it?

@alexander-akait
Copy link
Member

yep 😞 we have sockPort for this case now #1792, feel free to send a PR with revert

@gtzampanakis
Copy link

This broke my setup as well. I have an HTML page that references two bundles. Each of them is served from a different WDS instance, running on a different port.

@alexander-akait
Copy link
Member

PR welcome to revert

@webpack webpack locked as too heated and limited conversation to collaborators Apr 17, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants