rework/lightweight #12

Merged
GauthierWebDev merged 106 commits from rework/lightweight into main 2025-04-21 16:27:38 +00:00
9 changed files with 158 additions and 129 deletions
Showing only changes of commit 67140bb47e - Show all commits

4
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"biome.searchInPath": false,
"biome.lspBin": "app/node_modules/@biomejs/biome/bin/biome",
}

View File

@ -6,8 +6,16 @@ function getEnvironmentVariable<T = undefined>(key: string, defaultValue: T, for
return value as T; return value as T;
} }
const PORT = getEnvironmentVariable<number>('PORT', 3000, (data) => parseInt(data, 10)); function getEnvironmentVariableOrThrow<T = undefined>(key: string, formatter?: (data: string) => T): T {
const HMR_PORT = getEnvironmentVariable<number>('HMR_PORT', PORT + 1, (data) => parseInt(data, 10)); const value = process.env[key];
if (value === undefined) throw new Error(`Missing environment variable: ${key}`);
if (formatter) return formatter(value);
return value as T;
}
const PORT = getEnvironmentVariableOrThrow<number>('PORT', (data) => parseInt(data, 10));
const HMR_PORT = getEnvironmentVariableOrThrow<number>('HMR_PORT', (data) => parseInt(data, 10));
const BASE_URL = getEnvironmentVariable<string>('BASE_URL', `http://localhost:${PORT}`); const BASE_URL = getEnvironmentVariable<string>('BASE_URL', `http://localhost:${PORT}`);
const NODE_ENV = getEnvironmentVariable<string>('NODE_ENV', 'development'); const NODE_ENV = getEnvironmentVariable<string>('NODE_ENV', 'development');

View File

@ -1,67 +1,64 @@
import { dirname } from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import { dirname } from "node:path";
import { vikeHandler } from "./server/vike-handler";
import { telefuncHandler } from "./server/telefunc-handler";
import Fastify from "fastify";
import { createHandler } from "@universal-middleware/fastify"; import { createHandler } from "@universal-middleware/fastify";
import { telefuncHandler } from "./server/telefunc-handler";
import { vikeHandler } from "./server/vike-handler";
import { config } from "./config";
import Fastify from "fastify";
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename); const __dirname = dirname(__filename);
const root = __dirname; const root = __dirname;
const port = process.env.PORT ? parseInt(process.env.PORT, 10) : 3000;
const hmrPort = process.env.HMR_PORT ? parseInt(process.env.HMR_PORT, 10) : 24678;
async function startServer() { async function startServer() {
const app = Fastify(); const app = Fastify();
// Avoid pre-parsing body, otherwise it will cause issue with universal handlers // Avoid pre-parsing body, otherwise it will cause issue with universal handlers
// This will probably change in the future though, you can follow https://github.com/magne4000/universal-middleware for updates // This will probably change in the future though, you can follow https://github.com/magne4000/universal-middleware for updates
app.removeAllContentTypeParsers(); app.removeAllContentTypeParsers();
app.addContentTypeParser("*", function (_request, _payload, done) { app.addContentTypeParser("*", (_request, _payload, done) => done(null, ""));
done(null, "");
});
await app.register(await import("@fastify/middie")); await app.register(await import("@fastify/middie"));
if (process.env.NODE_ENV === "production") { if (process.env.NODE_ENV === "production") {
await app.register(await import("@fastify/static"), { await app.register(await import("@fastify/static"), {
root: `${root}/dist/client`, root: `${root}/dist/client`,
wildcard: false, wildcard: false,
}); });
} else { } else {
// Instantiate Vite's development server and integrate its middleware to our server. // Instantiate Vite's development server and integrate its middleware to our server.
// ⚠️ We should instantiate it *only* in development. (It isn't needed in production // ⚠️ We should instantiate it *only* in development. (It isn't needed in production
// and would unnecessarily bloat our server in production.) // and would unnecessarily bloat our server in production.)
const vite = await import("vite"); const vite = await import("vite");
const viteDevMiddleware = ( const viteDevMiddleware = (
await vite.createServer({ await vite.createServer({
root, root,
server: { middlewareMode: true, hmr: { port: hmrPort } }, server: { middlewareMode: true, hmr: { port: config.HMR_PORT } },
}) })
).middlewares; ).middlewares;
app.use(viteDevMiddleware); app.use(viteDevMiddleware);
} }
app.post<{ Body: string }>("/_telefunc", createHandler(telefuncHandler)()); app.post<{ Body: string }>("/_telefunc", createHandler(telefuncHandler)());
/** /**
* Vike route * Vike route
* *
* @link {@see https://vike.dev} * @link {@see https://vike.dev}
**/ **/
app.all("/*", createHandler(vikeHandler)()); app.all("/*", createHandler(vikeHandler)());
return app; return app;
} }
const app = await startServer(); const app = await startServer();
app.listen( app.listen({ port: config.PORT, host: "0.0.0.0" }, (error, address) => {
{ if (error) {
port: port, app.log.error(error);
}, process.exit(1);
() => { }
console.log(`Server listening on http://localhost:${port}`);
}, console.log(`Server listening on ${address}`);
); });

View File

@ -1,50 +1,52 @@
import "./style.css"; import type { JSX } from "solid-js";
import "./tailwind.css"; import "./tailwind.css";
import type { JSX } from "solid-js";
import logoUrl from "../assets/logo.svg"; import logoUrl from "../assets/logo.svg";
import { Link } from "../components/Link.js"; import { Link } from "../components/Link.js";
export default function LayoutDefault(props: { children?: JSX.Element }) { export default function LayoutDefault(props: { children?: JSX.Element }) {
return ( return (
<div class={"flex max-w-5xl m-auto"}> <div class={"flex max-w-5xl m-auto"}>
<Sidebar> <Sidebar>
<Logo /> <Logo />
<Link href="/">Welcome</Link> <Link href="/">Welcome</Link>
<Link href="/todo">Todo</Link> <Link href="/todo">Todo</Link>
<Link href="/star-wars">Data Fetching</Link> <Link href="/star-wars">Data Fetching</Link>
{""} {""}
</Sidebar> </Sidebar>
<Content>{props.children}</Content> <Content>{props.children}</Content>
</div> </div>
); );
} }
function Sidebar(props: { children: JSX.Element }) { function Sidebar(props: { children: JSX.Element }) {
return ( return (
<div id="sidebar" class={"p-5 flex flex-col shrink-0 border-r-2 border-r-gray-200"}> <div
{props.children} id="sidebar"
</div> class={"p-5 flex flex-col shrink-0 border-r-2 border-r-gray-200"}
); >
{props.children}
</div>
);
} }
function Content(props: { children: JSX.Element }) { function Content(props: { children: JSX.Element }) {
return ( return (
<div id="page-container"> <div id="page-container">
<div id="page-content" class={"p-5 pb-12 min-h-screen"}> <div id="page-content" class={"p-5 pb-12 min-h-screen"}>
{props.children} {props.children}
</div> </div>
</div> </div>
); );
} }
function Logo() { function Logo() {
return ( return (
<div class={"p-5 mb-2"}> <div class={"p-5 mb-2"}>
<a href="/"> <a href="/">
<img src={logoUrl} height={64} width={64} alt="logo" /> <img src={logoUrl} height={64} width={64} alt="logo" />
</a> </a>
</div> </div>
); );
} }

View File

@ -1 +1,2 @@
@import "./style.css";
@import "tailwindcss"; @import "tailwindcss";

View File

@ -1,38 +1,39 @@
{ {
"scripts": { "scripts": {
"dev": "bun ./fastify-entry.ts", "dev": "bun ./fastify-entry.ts",
"build": "vike build", "build": "vike build",
"preview": "cross-env NODE_ENV=production bun ./fastify-entry.ts", "preview": "cross-env NODE_ENV=production bun ./fastify-entry.ts",
"lint": "biome lint --write .", "production": "bun run build && bun run preview",
"format": "biome format --write ." "lint": "biome lint --write .",
}, "format": "biome format --write ."
"dependencies": { },
"vike": "^0.4.228", "dependencies": {
"@fastify/middie": "^9.0.3", "vike": "^0.4.228",
"@fastify/static": "^8.1.1", "@fastify/middie": "^9.0.3",
"@universal-middleware/fastify": "^0.5.16", "@fastify/static": "^8.1.1",
"fastify": "^5.3.0", "@universal-middleware/fastify": "^0.5.16",
"@universal-middleware/core": "^0.4.7", "fastify": "^5.3.0",
"solid-js": "^1.9.5", "@universal-middleware/core": "^0.4.7",
"vike-solid": "^0.7.9", "solid-js": "^1.9.5",
"telefunc": "^0.2.3" "vike-solid": "^0.7.9",
}, "telefunc": "^0.2.3"
"devDependencies": { },
"@biomejs/biome": "1.9.4", "devDependencies": {
"@eslint/js": "^9.24.0", "@biomejs/biome": "1.9.4",
"@tailwindcss/vite": "^4.1.3", "@eslint/js": "^9.24.0",
"@types/node": "^18.19.86", "@tailwindcss/vite": "^4.1.3",
"cross-env": "^7.0.3", "@types/node": "^18.19.86",
"eslint": "^9.24.0", "cross-env": "^7.0.3",
"eslint-config-prettier": "^10.1.2", "eslint": "^9.24.0",
"eslint-plugin-prettier": "^5.2.6", "eslint-config-prettier": "^10.1.2",
"eslint-plugin-solid": "^0.14.5", "eslint-plugin-prettier": "^5.2.6",
"globals": "^16.0.0", "eslint-plugin-solid": "^0.14.5",
"prettier": "^3.5.3", "globals": "^16.0.0",
"tailwindcss": "^4.1.3", "prettier": "^3.5.3",
"typescript": "^5.8.3", "tailwindcss": "^4.1.3",
"typescript-eslint": "^8.29.1", "typescript": "^5.8.3",
"vite": "^6.2.6" "typescript-eslint": "^8.29.1",
}, "vite": "^6.2.6"
"type": "module" },
} "type": "module"
}

View File

@ -1,17 +1,20 @@
import vikeSolid from "vike-solid/config";
import type { Config } from "vike/types"; import type { Config } from "vike/types";
import vikeSolid from "vike-solid/config";
import Layout from "../layouts/LayoutDefault.js"; import Layout from "../layouts/LayoutDefault.js";
// Default config (can be overridden by pages) // Default config (can be overridden by pages)
// https://vike.dev/config // https://vike.dev/config
export default { export default {
// https://vike.dev/Layout // https://vike.dev/Layout
Layout, Layout,
// https://vike.dev/head-tags // https://vike.dev/head-tags
title: "My Vike App", title: "My Vike App",
description: "Demo showcasing Vike", description: "Demo showcasing Vike",
extends: vikeSolid, prerender: true,
extends: vikeSolid,
} satisfies Config; } satisfies Config;

View File

@ -1,5 +1,5 @@
{ {
"$schema": "https://biomejs.dev/schemas/1.7.3/schema.json", "$schema": "./app/node_modules/@biomejs/biome/configuration_schema.json",
"organizeImports": { "organizeImports": {
"enabled": true "enabled": true
}, },

View File

@ -1,5 +1,5 @@
services: services:
app: dev:
container_name: memento-dev container_name: memento-dev
image: oven/bun:alpine image: oven/bun:alpine
env_file: env_file:
@ -11,3 +11,16 @@ services:
- ./app:/app - ./app:/app
working_dir: /app working_dir: /app
command: bun run dev command: bun run dev
prod:
container_name: memento-prod
image: oven/bun:alpine
env_file:
- .env
ports:
- "${PORT}:${PORT}"
- "${HMR_PORT}:${HMR_PORT}"
volumes:
- ./app:/app
working_dir: /app
command: bun run production