serve-handler
serve-handler copied to clipboard
Rewriting URL to remove prefix from request
Problem-Description
I get my requests to the following URL /some/frontend/static/js/main.js.
My build folder to be served has the following structure
build
|_ static
|_ js
|_ main.js
Therefore serve should translate the url /some/frontend/static/js/main.js into the path static/js/main.js.
As far as I know a rewrite would be the way to go. However it doesnt work out for me, instead I found out serve creates a wrong path for me.
serve.json
{
"rewrites": [{ "source": "/some/frontend/:path*", "destination": "/:path" }]
}
The serve handler translates the path into /static%2Fjs%2Fmain.5a829761.js. So he is escaping it.
This comes from line 70 in the index.js file, where the translation takes place.
Is there a way to define my rewrite route correctly?
This is definitely a very common task that one need to perform
Imagine you have a large organization running a commercial website call it acme.com
There are multiple React Apps, written by multiple teams, deployed to this website, for example:
- app1
- app2
Say the network admin has configured requests to go from acme.com/app1 to go to host1 and acme.com/app2 to host2
Where host1/host2 are machines running serve-handler ...
@erfangc I know that this is pretty common task. Thats why I want to do that, however, It seemed that this is not possible using serve. Can you provide an example of how to write that correctly?
@PetrykowskiM I am in your boat, I am saying this is a fairly common practice so I imagine there must be a way to do it
I've tried a variety of things without much success either
Ok, good to know than! Well, would be nice if anybody else could help.
@PetrykowskiM I am find many things difficult with this one
first - rewrites do not really work ... so that sucks
second -
I tried structuring the directory such that host/app/index.html corresponds to the local FS app/index.html
The second approach succeeded (but you need to disable directoryList) through the serve.json config
But then (I am assuming you are writing a SPA in Angular/React/Vue) ... then if you are using any Router(s) in the SPA, you are going to run into all sorts of unexpected problems. This is seemingly benign task is proving to be surprisingly difficult. I hope I am just being stupid here and missing something obvious
Seems like the proposal in #27
path-to-regexp supports repeated segments
const toPathRepeated = compile("/:segment+"); toPathRepeated({ segment: "foo" }); //=> "/foo" toPathRepeated({ segment: ["a", "b", "c"] }); //=> "/a/b/c"
I think that should be the solution 🤔
{
"rewrites": [{
"source": "/some/frontend/:path+",
"destination": "/:path"
}]
}
@AndyOGo's solution looks like it wasn't tested, because with it I still get the same issue.
Here is my abridged serve.json:
{
...
"rewrites": [
{
"source": "/some/path/:path+",
"destination": "/:path"
}
]
}
And here is my abridged curl output after running npx serve:
user@Machine project-root % curl -I http://localhost:3000/favicon.png
HTTP/1.1 200 OK
...
user@Machine project-root % curl -I http://localhost:3000/some/path/favicon.png
HTTP/1.1 200 OK
...
user@Machine project-root % curl -I http://localhost:3000/assets/vendor.822f96e6.js
HTTP/1.1 200 OK
...
user@Machine project-root % curl -I http://localhost:3000/some/path/assets/vendor.822f96e6.js
HTTP/1.1 404 Not Found
...
shameless self-promotion alert:
this feature is fixed in my @warren-bank/serve fork of serve
notes:
- rewrite rules now require an
engineattribute..
which permits you to choose which methodology/library is used to:- match the url pathname against a pattern
- replace capture groups
Any updates here?
If you want to remove prefixes from in-app requests, continue using rewrites. That works fine.
The
rewritesis intended to rewrite the url routing within the app andservecannot know when the initial static path is requested.
If you want to serve static js/css files from a path different than /static, here is the solution.
Assume you want to serve your frontend under foo.com/frontend.
- In your build directory, move the
staticfolder tofrontend/static. - Change
index.htmlto point new static paths, e.g.:/static/js/main.xyz.jsto/frontend/static/js/main.xyz.jsand/static/css/main.xyz.cssto/frontend/static/js/main.xyz.css - Run
serve. Make sure the request initiator chain points to/frontend/static/...: