silphius/server.js

116 lines
3.3 KiB
JavaScript
Raw Permalink Normal View History

2024-06-10 19:35:19 -05:00
import {createRequestHandler} from '@remix-run/express';
import compression from 'compression';
import express from 'express';
import morgan from 'morgan';
2024-07-24 02:23:12 -05:00
// patch pixi server context
import('./app/server/pixi-context.js');
2024-06-10 19:35:19 -05:00
const isProduction = process.env.NODE_ENV === 'production';
2024-06-29 06:28:27 -05:00
const isInsecure = process.env.SILPHIUS_INSECURE_HTTP;
2024-06-10 19:35:19 -05:00
const app = express();
let server;
2024-06-29 06:28:27 -05:00
if (isInsecure) {
2024-06-10 19:35:19 -05:00
const {createServer} = await import('node:http');
server = createServer(app);
}
else {
const {execSync} = await import('node:child_process');
const {mkdirSync, readFileSync, statSync} = await import('node:fs');
const cacheDirectory = `${import.meta.dirname}/node_modules/.cache`;
mkdirSync(cacheDirectory, {recursive: true});
try {
statSync(`${cacheDirectory}/localhost-key.pem`);
}
catch (error) { // eslint-disable-line no-unused-vars
execSync(`mkcert -cert-file ${cacheDirectory}/localhost.pem -key-file ${cacheDirectory}/localhost-key.pem localhost`)
}
const serverOptions = {
key: readFileSync(`${cacheDirectory}/localhost-key.pem`),
cert: readFileSync(`${cacheDirectory}/localhost.pem`),
};
const {createServer} = await import('node:https');
server = createServer(serverOptions, app);
}
2024-07-24 02:23:12 -05:00
// immediately start listening and queueing up connections
let resolve, promise = new Promise((res) => {
resolve = res;
});
app.use(async (req, res, next) => {
await promise;
next();
});
const port = process.env.PORT || 3000;
server.listen(port, () =>
console.log(`Express server listening at http${isInsecure ? '' : 's'}://localhost:${port}`)
);
// possibly load dev server and build the request handler up front
2024-06-10 19:35:19 -05:00
const viteDevServer = isProduction
? undefined
: await import('vite').then((vite) =>
vite.createServer({
server: {middlewareMode: {server}},
})
);
2024-07-24 02:23:12 -05:00
const build = () => (
viteDevServer
? viteDevServer.ssrLoadModule('virtual:remix/server-build')
: import('./build/server/index.js')
);
2024-09-18 01:32:26 -05:00
let remixHandler;
if (viteDevServer) {
const {createViteRuntime} = await import('vite');
const runtime = await createViteRuntime(viteDevServer);
const {handleUpgrade} = await runtime.executeEntrypoint('/app/server/websocket.js');
server.on('upgrade', handleUpgrade);
remixHandler = createRequestHandler({build});
}
else {
const ssr = await build();
server.on('upgrade', ssr.entry.module.handleUpgrade);
remixHandler = createRequestHandler({
build: async () => {
return ssr;
},
});
}
2024-06-10 19:35:19 -05:00
2024-07-24 02:23:12 -05:00
// configure middleware
2024-06-10 19:35:19 -05:00
app.use(compression());
// http://expressjs.com/en/advanced/best-practice-security.html#at-a-minimum-disable-x-powered-by-header
app.disable('x-powered-by');
// handle asset requests
if (viteDevServer) {
app.use(viteDevServer.middlewares);
}
else {
// Vite fingerprints its assets so we can cache forever.
app.use(
'/assets',
express.static('build/client/assets', { immutable: true, maxAge: '1y' })
);
2024-09-17 17:48:12 -05:00
// Everything else (like favicon.ico) is cached for an hour. You may want to be
// more aggressive with this caching.
app.use(express.static('build/client', { maxAge: '1h' }));
2024-06-10 19:35:19 -05:00
}
2024-09-17 01:25:39 -05:00
// silphius resources
app.use(
'/resources',
express.static('resources', { maxAge: '1h' }),
);
2024-06-10 19:35:19 -05:00
app.use(morgan('tiny'));
// handle SSR requests
app.all('*', remixHandler);
2024-07-24 02:23:12 -05:00
// finally let requests resolve
resolve();