Skip to content

Instantly share code, notes, and snippets.

@Valexr
Forked from martinrue/serve.js
Created February 28, 2023 16:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Valexr/f2b17be07f0226e4b4e218ff2143ac5f to your computer and use it in GitHub Desktop.
Save Valexr/f2b17be07f0226e4b4e218ff2143ac5f 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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment