-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
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
Add proxy option to package.json #282
Conversation
I think earlier you mentioned the intent to avoid any 'webpackisms' - this doesn't seem to be one as there are likely to be similar solutions in any alternative ecosystems, if I understand correctly? |
Yea, this would work with any Express server. |
Note that this is somewhat limited but fixes what I think will be the most common use case. As an example of a limitation, you can’t proxy |
I like that it matches Could we just call the field in package.json |
Also, it's probably useful to distinguish in examples:
I suspect for most use cases people will want to use something ending with Also it's good to be clear that this does not proxy Is this proxying websockets as well? It probably should |
Updated the original post with the new proposal. |
So if someone specifies just If my understanding is correct there, I bet this becomes a common source of errors, people specifying the proxy without any path and then being confused when it proxies nothing. So maybe you could make it an error when a proxy is specified like that. Also, just in terms of naming, you like |
No, it proxies any unrecognised request with the new proposal. Actually in 99% cases this is exactly what you want to specify. |
So, to be clear, you almost always want to specify it like |
I'm generally okay with calling it |
Also new proposal doesn't support any expansions like |
} | ||
|
||
// Otherwise, if devProxy is specified, we will let it handle any request | ||
// that isn't /index.html or /sockjs-node/* (used for hot reloading). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we let the proxy handle a request for /
? I think the request from a browser will not actually be for /index.html
most of the time, it will be for /
, which makes some of these comments a bit confusing. I think the behavior is actually the same between /index.html
and /
though.
Ah I missed how much you had updated the proposal. I'm not familiar with configurations needing the A couple questions around edge cases. Can you proxy to Will this proxy websockets? |
It is necessary for any app with client side routing. If you use HTML5 history APIs you can update URL on the client without actually navigating. So user may end up on e.g.
I think so but I'm not sure how to verify. I'll try changing that server example to serve over https.
It is valid, it would just mean that /lol becomes http://localhost:4000/api/lol. I'm not sure how useful that is but I don't see harm in allowing this.
It should (I passed an option for that) but need to verify. |
OK, I tested this more. I couldn’t get WebSockets working so I disabled proxying them completely. They don’t suffer from CORS problems anyway by default so I don’t think this is super valuable. If somebody cares much about supporting them, they can send a PR. |
Thank you for adding the proxy feature! So for websocket calls one would point the url directly to the server specified in package.json for development. Is there a suggested way to build the url so that it works for both running under development mode and production? i.e. I guess is there a way to tell if you're running under dev or production and is there a way to access the proxy value from package.json? |
Specifically:
if (process.env.NODE_ENV === 'production') {
// ...
}
No. |
Thanks for clarifying @gaearon, I can work with that. |
@gaearon to clarify, is this proxy meant to be on production or just development? I very common use case for proxy is both development and production. I really want to use create-react-app for production but am still struggling to find an easy straight forward solution for multiple staging environments, proxies, and customizing things like css modules etc. I'm still a bit new to this project and will contribute after my current project isn't so crazy. Thanks for the great work |
This proxy feature is great, but I wasn't able to determine if it is possible to define multiple proxy servers?This is relevant in my case because the authentication and api servers are separate. |
@apet-as I'm afraid this is a more advanced use case, and we won't support it out of the box. You can use custom environment variables for this to determine the endpoints instead in your JS code. The user guide includes information on using custom variables. |
@gaearon Thanks for the reply :) I am quite new to this environment(node) and toolset, but I am unsure how that would allow me to solve the issue in this case. To clarify with a bit more detail I want to proxy requests made to /api/oauth to auth.domain.com and requests made to /api/rest to api.domain.com without restarting the application to swap between them. I understand that configuring environment variables would allow you to configure what proxy endpoint is used when the server starts but I don't see how I could use that to switch the endpoint dynamically while it is running? |
You can't really proxy anything by yourself solely in the client code. But you could create a single wrapper function that you use for every single request. That function could use specified endpoint in production, but tweak it in development in any way you want. |
In this case I am talking solely about development, when I am running the react app in localhost, I don't intend to deploy this as is to production. I am trying to use it as a way to learn, build and test concepts and shared code for other javascript applications that use this api. The api service is not being run locally on my machine so I need to avoid cors issues. The part I don't understand is how my client code could dynamically tweak the webpack server proxy endpoint on the fly in development. |
I understand if this is not really a core use case for the target audience but I am trying to achieve something to the effect of: "proxy" : { |
Sorry, as I explained above, if you need to proxy to multiple locations, you can't use the
It can't. My point was that since you can't use the function myFetch(url, ...args) {
if (process.env.NODE_ENV === 'development') {
url = url.replace('/api/oauth', 'https://auth.endpoint.com');
url = url.replace('/api/rest', 'https://api.endpoint.com');
}
return fetch(url, ...args);
} and then using it throughout your project. This doesn't handle CORS so it doesn't work the same way as |
@gaearon Thanks, that is what I figured. Already handling the different endpoints in code fine it is just the CORS issue I was struggling with. |
@gaearon Can you give me a hint why in my application '/graphql' requests passed through the proxy are transformed from POST to GET and consequently loose body content? I'm using it like this: |
@esseswann Sorry, I don't know. If you have any problems please create an issue explaining them. |
@gaearon No probs, I'll create an issue if I manage to reproduce |
(The proposal was updated since the original posting.)
This is a proof of concept of solution to #147.
It works for simple cases, and I think it’s fairly unobtrusive.
It lets you add a field to
package.json
like this:Then any unrecognized requests (i.e. aren’t request to bundled assets) will be forwarded to that base URL. This is very similar to how our existing
/index.html
fallback works for client side routing.There is one gotcha: of course
/index.html
fallback andproxy
(when specified) would compete. I resolved this with a heuristic that I think would work in the vast majority of cases.If
proxy
is specified, we make/index.html
fallback a little bit less aggressive, and we only activate it if specificallytext/html
is present in theaccept
header. In practice every modern browser (not IE8 but we don’t support it anyway) sends it when you navigate to a page, so/index.html
fallback will keep on working just fine for client-side apps. However, if you usefetch()
,$.ajax()
,axios()
orXMLHttpRequest
without explicitly puttingtext/html
there, we will happily proxy your request todevProxy
.To illustrate this:
When
proxy
is not specified,/index.html
fallback kicks in every time, just like now. So this behavior is completely opt-in.If for some reason the heuristic fails for your project (maybe you just have to
fetch()
some HTML... templates?), well, you can’t useproxy
. It is only a convenience. Please use the regular method (which is not that hard anyway—you’d have to add CORS to your server and hardcode the server URL into your client, just like you would do now anyway).I feel this could be a good compromise that lets people get started without worrying about CORS.