-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
159 lines (127 loc) · 4.18 KB
/
server.js
File metadata and controls
159 lines (127 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Node standard libs
import os from "node:os";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
// Server libs
import express from "express";
import { createServer as createViteServer } from "vite";
import sirv from "sirv";
// Console formatting libs
import chalk from "chalk";
import boxen from "boxen";
// Other libs
import { program } from "commander";
// CLI Arguments
program.option("-p, --port <value>");
program.option("-h, --host <value>");
program.parse();
const options = program.opts();
// Constants
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const isProduction = process.env.NODE_ENV === "production";
const port = parseInt(options.port) || 5173;
const host = options.host || "localhost";
/**
* formats a log message for a server request
* @param req - The server request object
*/
function logRequest(req) {
const protocol = chalk.bgBlueBright
.hex("#FFF")
.bold(` ${req.protocol.toUpperCase()} `);
const date_string = new Date().toLocaleString().replace(",", "");
const client_ip = chalk.yellow(req.ip.replace("::ffff:", ""));
const request = chalk.cyan(`${req.method} ${req.originalUrl}`);
return `${protocol} ${date_string} ${client_ip} ${request}`;
}
/**
* Gets the IP address(s) of the server
*/
function getIps() {
let net_faces = os.networkInterfaces();
let ips = [];
// Iterate over network interfaces
Object.values(net_faces).forEach((net_face) => {
if (net_face === undefined) return;
// Iterate over network interface info
net_face.forEach((net_face_info) => {
// Skip over internal and non-IPv4 addresses
if (net_face_info.family !== "IPv4" || net_face_info.internal) return;
ips.push(net_face_info.address);
});
});
return ips;
}
/** Creates an http server for serving an SSR app */
async function createServer() {
const app = express();
let vite;
if (!isProduction) {
// Use vite dev server if in development environment
console.log(chalk.blue("Starting server in development mode..."));
// Create Vite server in middleware mode
vite = await createViteServer({
server: { middlewareMode: true },
appType: "custom", // Disables vites HTML serving logic
});
app.use(vite.middlewares);
} else {
// Use sirv for static asset serving if in production environment
console.log(chalk.blue("Starting server in production mode..."));
app.use(sirv("dist/client", { gzip: true }));
}
app.use("*", async (req, res) => {
const url = req.originalUrl;
let template, render;
try {
if (!isProduction) console.log(logRequest(req));
if (!isProduction) {
// Read index.html
template = fs.readFileSync(
path.resolve(__dirname, "index.html"),
"utf8",
);
// Apply vite HTML transforms
template = await vite.transformIndexHtml(url, template);
render = (await vite.ssrLoadModule("/src/entry-server.tsx")).render;
} else {
template = fs.readFileSync(
path.resolve("dist/client/index.html"),
"utf-8",
);
render = (await import("./dist/server/entry-server.js")).render;
}
// Render app html
const appHtml = await render(req);
// Inject rendered app html into index.html template
const html = template.replace("<!--ssr-outlet-->", appHtml);
// Send rendered html to client
res.statusCode = 200;
res.setHeader("Content-Type", "text/html").end(html);
} catch (e) {
if (!isProduction) vite.ssrFixStacktrace(e);
console.error(e);
res.status(500).end(e);
}
});
return app;
}
// Create server and start listening for http requests
createServer().then((app) => {
app.listen(port, host);
const server_host = host === "0.0.0.0" ? getIps()[0] : host;
let start_message = `${chalk.bold("- Local:")} http://localhost:${port}`;
if (host === "0.0.0.0")
start_message += `\n${chalk.bold("- Network:")} http://${server_host}:${port}`;
console.log("");
console.log(
boxen(start_message, {
margin: 1,
padding: 1,
borderColor: "green",
title: "Server Started",
titleAlignment: "center",
}),
);
});