From 67140bb47ec013789a2be5cd0506367782a8208c Mon Sep 17 00:00:00 2001 From: GauthierWebDev Date: Sat, 19 Apr 2025 13:45:33 +0200 Subject: [PATCH] feat: Add production script to package.json --- .vscode/settings.json | 4 ++ app/config.ts | 12 ++++- app/fastify-entry.ts | 93 +++++++++++++++++------------------ app/layouts/LayoutDefault.tsx | 68 ++++++++++++------------- app/layouts/tailwind.css | 1 + app/package.json | 75 ++++++++++++++-------------- app/pages/+config.ts | 17 ++++--- app/biome.json => biome.json | 2 +- compose.yml | 15 +++++- 9 files changed, 158 insertions(+), 129 deletions(-) create mode 100644 .vscode/settings.json rename app/biome.json => biome.json (74%) diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9b30720 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "biome.searchInPath": false, + "biome.lspBin": "app/node_modules/@biomejs/biome/bin/biome", +} \ No newline at end of file diff --git a/app/config.ts b/app/config.ts index 440f43a..1c3a4e1 100644 --- a/app/config.ts +++ b/app/config.ts @@ -6,8 +6,16 @@ function getEnvironmentVariable(key: string, defaultValue: T, for return value as T; } -const PORT = getEnvironmentVariable('PORT', 3000, (data) => parseInt(data, 10)); -const HMR_PORT = getEnvironmentVariable('HMR_PORT', PORT + 1, (data) => parseInt(data, 10)); +function getEnvironmentVariableOrThrow(key: string, formatter?: (data: string) => T): T { + 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('PORT', (data) => parseInt(data, 10)); +const HMR_PORT = getEnvironmentVariableOrThrow('HMR_PORT', (data) => parseInt(data, 10)); const BASE_URL = getEnvironmentVariable('BASE_URL', `http://localhost:${PORT}`); const NODE_ENV = getEnvironmentVariable('NODE_ENV', 'development'); diff --git a/app/fastify-entry.ts b/app/fastify-entry.ts index 1b3b99a..ef2017a 100755 --- a/app/fastify-entry.ts +++ b/app/fastify-entry.ts @@ -1,67 +1,64 @@ -import { dirname } from "node:path"; 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 { 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 __dirname = dirname(__filename); 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() { - const app = Fastify(); + const app = Fastify(); - // 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 - app.removeAllContentTypeParsers(); - app.addContentTypeParser("*", function (_request, _payload, done) { - done(null, ""); - }); + // 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 + app.removeAllContentTypeParsers(); + app.addContentTypeParser("*", (_request, _payload, done) => done(null, "")); - await app.register(await import("@fastify/middie")); + await app.register(await import("@fastify/middie")); - if (process.env.NODE_ENV === "production") { - await app.register(await import("@fastify/static"), { - root: `${root}/dist/client`, - wildcard: false, - }); - } else { - // 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 - // and would unnecessarily bloat our server in production.) - const vite = await import("vite"); - const viteDevMiddleware = ( - await vite.createServer({ - root, - server: { middlewareMode: true, hmr: { port: hmrPort } }, - }) - ).middlewares; - app.use(viteDevMiddleware); - } + if (process.env.NODE_ENV === "production") { + await app.register(await import("@fastify/static"), { + root: `${root}/dist/client`, + wildcard: false, + }); + } else { + // 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 + // and would unnecessarily bloat our server in production.) + const vite = await import("vite"); + const viteDevMiddleware = ( + await vite.createServer({ + root, + server: { middlewareMode: true, hmr: { port: config.HMR_PORT } }, + }) + ).middlewares; + app.use(viteDevMiddleware); + } - app.post<{ Body: string }>("/_telefunc", createHandler(telefuncHandler)()); + app.post<{ Body: string }>("/_telefunc", createHandler(telefuncHandler)()); - /** - * Vike route - * - * @link {@see https://vike.dev} - **/ - app.all("/*", createHandler(vikeHandler)()); + /** + * Vike route + * + * @link {@see https://vike.dev} + **/ + app.all("/*", createHandler(vikeHandler)()); - return app; + return app; } const app = await startServer(); -app.listen( - { - port: port, - }, - () => { - console.log(`Server listening on http://localhost:${port}`); - }, -); +app.listen({ port: config.PORT, host: "0.0.0.0" }, (error, address) => { + if (error) { + app.log.error(error); + process.exit(1); + } + + console.log(`Server listening on ${address}`); +}); diff --git a/app/layouts/LayoutDefault.tsx b/app/layouts/LayoutDefault.tsx index b3e3aa9..452bc18 100755 --- a/app/layouts/LayoutDefault.tsx +++ b/app/layouts/LayoutDefault.tsx @@ -1,50 +1,52 @@ -import "./style.css"; +import type { JSX } from "solid-js"; import "./tailwind.css"; -import type { JSX } from "solid-js"; import logoUrl from "../assets/logo.svg"; import { Link } from "../components/Link.js"; export default function LayoutDefault(props: { children?: JSX.Element }) { - return ( -
- - - Welcome - Todo - Data Fetching - {""} - - {props.children} -
- ); + return ( +
+ + + Welcome + Todo + Data Fetching + {""} + + {props.children} +
+ ); } function Sidebar(props: { children: JSX.Element }) { - return ( - - ); + return ( + + ); } function Content(props: { children: JSX.Element }) { - return ( -
-
- {props.children} -
-
- ); + return ( +
+
+ {props.children} +
+
+ ); } function Logo() { - return ( -
- - logo - -
- ); + return ( +
+ + logo + +
+ ); } diff --git a/app/layouts/tailwind.css b/app/layouts/tailwind.css index f1d8c73..44f8c8f 100755 --- a/app/layouts/tailwind.css +++ b/app/layouts/tailwind.css @@ -1 +1,2 @@ +@import "./style.css"; @import "tailwindcss"; diff --git a/app/package.json b/app/package.json index ec158b2..e2413e5 100755 --- a/app/package.json +++ b/app/package.json @@ -1,38 +1,39 @@ { - "scripts": { - "dev": "bun ./fastify-entry.ts", - "build": "vike build", - "preview": "cross-env NODE_ENV=production bun ./fastify-entry.ts", - "lint": "biome lint --write .", - "format": "biome format --write ." - }, - "dependencies": { - "vike": "^0.4.228", - "@fastify/middie": "^9.0.3", - "@fastify/static": "^8.1.1", - "@universal-middleware/fastify": "^0.5.16", - "fastify": "^5.3.0", - "@universal-middleware/core": "^0.4.7", - "solid-js": "^1.9.5", - "vike-solid": "^0.7.9", - "telefunc": "^0.2.3" - }, - "devDependencies": { - "@biomejs/biome": "1.9.4", - "@eslint/js": "^9.24.0", - "@tailwindcss/vite": "^4.1.3", - "@types/node": "^18.19.86", - "cross-env": "^7.0.3", - "eslint": "^9.24.0", - "eslint-config-prettier": "^10.1.2", - "eslint-plugin-prettier": "^5.2.6", - "eslint-plugin-solid": "^0.14.5", - "globals": "^16.0.0", - "prettier": "^3.5.3", - "tailwindcss": "^4.1.3", - "typescript": "^5.8.3", - "typescript-eslint": "^8.29.1", - "vite": "^6.2.6" - }, - "type": "module" -} \ No newline at end of file + "scripts": { + "dev": "bun ./fastify-entry.ts", + "build": "vike build", + "preview": "cross-env NODE_ENV=production bun ./fastify-entry.ts", + "production": "bun run build && bun run preview", + "lint": "biome lint --write .", + "format": "biome format --write ." + }, + "dependencies": { + "vike": "^0.4.228", + "@fastify/middie": "^9.0.3", + "@fastify/static": "^8.1.1", + "@universal-middleware/fastify": "^0.5.16", + "fastify": "^5.3.0", + "@universal-middleware/core": "^0.4.7", + "solid-js": "^1.9.5", + "vike-solid": "^0.7.9", + "telefunc": "^0.2.3" + }, + "devDependencies": { + "@biomejs/biome": "1.9.4", + "@eslint/js": "^9.24.0", + "@tailwindcss/vite": "^4.1.3", + "@types/node": "^18.19.86", + "cross-env": "^7.0.3", + "eslint": "^9.24.0", + "eslint-config-prettier": "^10.1.2", + "eslint-plugin-prettier": "^5.2.6", + "eslint-plugin-solid": "^0.14.5", + "globals": "^16.0.0", + "prettier": "^3.5.3", + "tailwindcss": "^4.1.3", + "typescript": "^5.8.3", + "typescript-eslint": "^8.29.1", + "vite": "^6.2.6" + }, + "type": "module" +} diff --git a/app/pages/+config.ts b/app/pages/+config.ts index 423f20b..1ba0b7b 100755 --- a/app/pages/+config.ts +++ b/app/pages/+config.ts @@ -1,17 +1,20 @@ -import vikeSolid from "vike-solid/config"; import type { Config } from "vike/types"; + +import vikeSolid from "vike-solid/config"; import Layout from "../layouts/LayoutDefault.js"; // Default config (can be overridden by pages) // https://vike.dev/config export default { - // https://vike.dev/Layout - Layout, + // https://vike.dev/Layout + Layout, - // https://vike.dev/head-tags - title: "My Vike App", - description: "Demo showcasing Vike", + // https://vike.dev/head-tags + title: "My Vike App", + description: "Demo showcasing Vike", - extends: vikeSolid, + prerender: true, + + extends: vikeSolid, } satisfies Config; diff --git a/app/biome.json b/biome.json similarity index 74% rename from app/biome.json rename to biome.json index d03d259..404ec45 100755 --- a/app/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.7.3/schema.json", + "$schema": "./app/node_modules/@biomejs/biome/configuration_schema.json", "organizeImports": { "enabled": true }, diff --git a/compose.yml b/compose.yml index dc74b50..fc7c3d1 100644 --- a/compose.yml +++ b/compose.yml @@ -1,5 +1,5 @@ services: - app: + dev: container_name: memento-dev image: oven/bun:alpine env_file: @@ -11,3 +11,16 @@ services: - ./app:/app working_dir: /app 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