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

Add proxy support #32

Merged
merged 8 commits into from
Sep 9, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 52 additions & 7 deletions commands/reshowcase
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const fs = require("fs");
const path = require("path");
const os = require("os");
const esbuild = require("esbuild");
const http = require("http");
const { htmlPlugin } = require("@craftamap/esbuild-plugin-html");

const toAbsolutePath = (filepath) => {
Expand Down Expand Up @@ -190,9 +191,11 @@ const getPort = () => {
}
};

const {pathRewrites, ...esCustomConfig} = customConfig;

const config = {
...defaultConfig,
...customConfig,
...esCustomConfig,
define: { ...defaultConfig.define, ...(customConfig.define || {}) },
plugins: [...defaultConfig.plugins, ...(customConfig.plugins || [])],
};
Expand All @@ -212,8 +215,6 @@ if (isBuild) {
});
} else {
const port = getPort();
const durationLabel = "[Reshowcase] Watch and serve started. Duration";
console.time(durationLabel);

esbuild
.context(config)
Expand All @@ -225,11 +226,55 @@ if (isBuild) {
process.exit(1);
})
.then((ctx) => {
return ctx.serve({ port: port, servedir: outputPath });
return ctx.serve({ servedir: outputPath })
Copy link
Member

Choose a reason for hiding this comment

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

kind of minor: as esbuild will pick up a random port if none is defined, and the esbuild server is created before the proxy one, maybe we could set esbuild port as port + 1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

To ensure that esbuild doesn't accidentally take useful port?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah to make sure that esbuild picks port 3000 and user passes 3000 as well from command line. I think it's very unlikely though if esbuild picks the first available port... feel free to ignore.

})
.then((_serveResult) => {
console.timeEnd(durationLabel);
console.error("[Reshowcase] Watch mode started on port:", port);
.then(esbuildServer => {
const server = http.createServer((req, res) => {
let options = {
path: req.url,
method: req.method,
};

const rewrite = pathRewrites?.find(rewrite => req.url.startsWith(rewrite.context))

if (rewrite) {
if (rewrite.socketPath) {
options.socketPath = rewrite.socketPath;
} else {
const url = new URL(rewrite.target);
options.host = url.hostname;
options.port = url.port;
options.headers = {
...req.headers,
...(rewrite.changeOrigin ? { host: `${options.host}:${options.port}` } : {})
};
}
} else {
options.host = esbuildServer.host;
options.port = esbuildServer.port;
}

const proxyReq = http.request(options, proxyRes => {
res.writeHead(proxyRes.statusCode, proxyRes.headers)
proxyRes.pipe(res, { end: true })
})

proxyReq.on("error", err => {
console.error("Proxy request error:", err);
res.writeHead(500, { "Content-Type": "text/plain" });
res.end("Internal Server Error");
});
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Probably should show less details here as well

Copy link
Member

Choose a reason for hiding this comment

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

I think in this case we want to know as much as possible. Would definitely keep them (the same comment about [Reshowcase] prefix applies).


req.pipe(proxyReq, { end: true })
})

server.listen(port, error => {
if (error) {
return console.error(error)
Copy link
Member

Choose a reason for hiding this comment

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

[Reshowcase] prefix.

}

console.log(`[Reshowcase] Server listening on port ${port}`)
Copy link
Member

Choose a reason for hiding this comment

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

Should we mention something about "watch mode"? The previous message was Watch and serve started.. Also the timings were useful (imo).

Copy link
Member

Choose a reason for hiding this comment

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

Also, would be useful to print full URL so that one can cmd-click from the terminal and open the browser tab directly, if desired.

})
})
.catch((error) => {
console.error("[Reshowcase] Esbuild serve start failed:", error);
Expand Down