Skip to content

Instantly share code, notes, and snippets.

@martinrue
Created March 18, 2021 16:49
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save martinrue/2896becdb8a5ed81761e11ff2ea5898e to your computer and use it in GitHub Desktop.
Save martinrue/2896becdb8a5ed81761e11ff2ea5898e to your computer and use it in GitHub Desktop.
Using esbuild's serve function for an SPA, equivalent to webpack's `devServer.historyApiFallback`.
const http = require("http");
const esbuild = require("esbuild");
const serve = async (servedir, listen) => {
// Start esbuild's local web server. Random port will be chosen by esbuild.
const { host, port } = await esbuild.serve({ servedir }, {});
// Create a second (proxy) server that will forward requests to esbuild.
const proxy = http.createServer((req, res) => {
// forwardRequest forwards an http request through to esbuid.
const forwardRequest = (path) => {
const options = {
hostname: host,
port,
path,
method: req.method,
headers: req.headers,
};
const proxyReq = http.request(options, (proxyRes) => {
if (proxyRes.statusCode === 404) {
// If esbuild 404s the request, assume it's a route needing to
// be handled by the JS bundle, so forward a second attempt to `/`.
return forwardRequest("/");
}
// Otherwise esbuild handled it like a champ, so proxy the response back.
res.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(res, { end: true });
});
req.pipe(proxyReq, { end: true });
};
// When we're called pass the request right through to esbuild.
forwardRequest(req.url);
});
// Start our proxy server at the specified `listen` port.
proxy.listen(listen);
};
// Serves all content from ./dist on :1234.
// If esbuild 404s the request, the request is attempted again
// from `/` assuming that it's an SPA route needing to be handled by the root bundle.
serve("dist", 1234);
@ritamcastro
Copy link

Thanks! This worked like a charm!
🙏 💜

@ValYouW
Copy link

ValYouW commented Dec 8, 2022

Thx!

@jardelbordignon
Copy link

It works perfectly 🚀
Thanks for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment