From 4fe1b7fef57c5e7343097ce3451af67fc8a9372b Mon Sep 17 00:00:00 2001 From: Trent Rand Date: Sun, 14 Jul 2024 16:07:52 -0700 Subject: [PATCH] feat: render application at build time Replace server-side rendering with build-time rendering for the entire application. - Eliminates the need for a server to be running - Renders all components at build time, including those that require client-side hydration - Simplifies the development process by automatically handling components that require client-side hydration --- bun.lockb | Bin 257866 -> 269388 bytes index.html | 23 -------- package.json | 12 ++-- {src/app => public}/favicon.ico | Bin {src/app => public}/icon.png | Bin {src/app => public}/icon.svg | 0 server.js | 53 ------------------ .../Flash.client.jsx => components/Flash.jsx} | 0 src/entry-client.jsx | 13 ----- src/entry-server.jsx | 15 ----- src/layouts/Head.jsx | 20 +++++++ src/layouts/Layout.jsx | 9 +++ src/pages/+config.js | 11 ++++ src/{app/App.jsx => pages/index/+Page.jsx} | 19 +++---- .../index/Page.test.jsx} | 0 src/utils/fastboot.js | 2 +- vite.config.js | 23 +++----- 17 files changed, 63 insertions(+), 137 deletions(-) delete mode 100644 index.html rename {src/app => public}/favicon.ico (100%) rename {src/app => public}/icon.png (100%) rename {src/app => public}/icon.svg (100%) delete mode 100644 server.js rename src/{app/Flash.client.jsx => components/Flash.jsx} (100%) delete mode 100644 src/entry-client.jsx delete mode 100644 src/entry-server.jsx create mode 100644 src/layouts/Head.jsx create mode 100644 src/layouts/Layout.jsx create mode 100644 src/pages/+config.js rename src/{app/App.jsx => pages/index/+Page.jsx} (92%) rename src/{app/App.test.jsx => pages/index/Page.test.jsx} (100%) diff --git a/bun.lockb b/bun.lockb index 5dbf326c492292be17872c812cf7f4b3cf3be763..f08b9a53177647a56d18dcced44f42b18002d2d6 100755 GIT binary patch delta 51669 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 diff --git a/index.html b/index.html deleted file mode 100644 index bff1342..0000000 --- a/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - flash.comma.ai - - -
- - - - diff --git a/package.json b/package.json index 067f6ce..a30e7ea 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,10 @@ "private": true, "type": "module", "scripts": { - "dev": "node server", - "build": "npm run build:client && npm run build:server", - "build:client": "vite build --outDir dist/client", - "build:server": "vite build --outDir dist/server --ssr src/entry-server.jsx", - "serve": "NODE_ENV=production node server", - "start": "vite preview", + "dev": "vite", + "build": "vite build", + "generate": "vite build --outDir dist/static && npm run build:server && node prerender", + "start": "vite build && vite preview", "lint": "eslint . --ext js,jsx --report-unused-disable-directives", "test": "vitest" }, @@ -43,6 +41,8 @@ "postcss": "^8.4.38", "react-router-dom": "^6.24.1", "tailwindcss": "^3.4.3", + "vike": "^0.4.179", + "vike-react": "^0.4.17", "vite": "^5.2.12", "vite-plugin-ssr": "^0.4.142", "vite-plugin-style-import": "^2.0.0", diff --git a/src/app/favicon.ico b/public/favicon.ico similarity index 100% rename from src/app/favicon.ico rename to public/favicon.ico diff --git a/src/app/icon.png b/public/icon.png similarity index 100% rename from src/app/icon.png rename to public/icon.png diff --git a/src/app/icon.svg b/public/icon.svg similarity index 100% rename from src/app/icon.svg rename to public/icon.svg diff --git a/server.js b/server.js deleted file mode 100644 index e0b0a62..0000000 --- a/server.js +++ /dev/null @@ -1,53 +0,0 @@ -import fs from 'fs' -import path from 'path' -import { fileURLToPath } from 'url' -import express from 'express' -import { createServer as createViteServer } from 'vite' - -const __dirname = path.dirname(fileURLToPath(import.meta.url)) - -async function createServer() { - const app = express() - - const vite = await createViteServer({ - server: { middlewareMode: true }, - appType: 'custom' - }) - - app.use(vite.middlewares) - - app.use('*', async (req, res) => { - const url = req.originalUrl - - try { - let template = fs.readFileSync( - path.resolve(__dirname, 'index.html'), - 'utf-8' - ) - - const styleModule = await vite.ssrLoadModule('/src/index.css') - const css = styleModule.default - - template = await vite.transformIndexHtml(url, template) - template = template.replace( - '', - `` - ) - - const { render } = await vite.ssrLoadModule('/src/entry-server.jsx') - const appHtml = await render(url) - - let html = template.replace(``, appHtml) - - res.status(200).set({ 'Content-Type': 'text/html' }).end(html) - } catch (e) { - vite.ssrFixStacktrace(e) - console.error(e) - res.status(500).end(e.message) - } - }) - - app.listen(5173) -} - -createServer() diff --git a/src/app/Flash.client.jsx b/src/components/Flash.jsx similarity index 100% rename from src/app/Flash.client.jsx rename to src/components/Flash.jsx diff --git a/src/entry-client.jsx b/src/entry-client.jsx deleted file mode 100644 index 66ddb84..0000000 --- a/src/entry-client.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './app/App' - -// import '@fontsource-variable/inter' -// import '@fontsource-variable/jetbrains-mono' - -ReactDOM.hydrateRoot( - document.getElementById('root'), - - - -) diff --git a/src/entry-server.jsx b/src/entry-server.jsx deleted file mode 100644 index ff903c3..0000000 --- a/src/entry-server.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import './index.css' -import React from 'react' -import ReactDOMServer from 'react-dom/server' -import { StaticRouter } from 'react-router-dom/server' -import App from './app/App' - -export function render(url) { - return ReactDOMServer.renderToString( - - - - - - ) -} diff --git a/src/layouts/Head.jsx b/src/layouts/Head.jsx new file mode 100644 index 0000000..3396ef1 --- /dev/null +++ b/src/layouts/Head.jsx @@ -0,0 +1,20 @@ +import React from 'react' +import iconUrl from '../../public/icon.svg' + +export default function HeadDefault() { + return ( + <> + + + + + + ); +} diff --git a/src/layouts/Layout.jsx b/src/layouts/Layout.jsx new file mode 100644 index 0000000..7febf1b --- /dev/null +++ b/src/layouts/Layout.jsx @@ -0,0 +1,9 @@ +import '../index.css' + +import React from 'react' + +export default function Layout({ children }) { + return ( + {children} + ) +} diff --git a/src/pages/+config.js b/src/pages/+config.js new file mode 100644 index 0000000..5a49bba --- /dev/null +++ b/src/pages/+config.js @@ -0,0 +1,11 @@ +import vikeReact from 'vike-react/config' +import Head from '../layouts/Head' +import Layout from '../layouts/Layout' + +export default { + Head, + Layout, + title: "flash.comma.ai", + extends: vikeReact, +} + diff --git a/src/app/App.jsx b/src/pages/index/+Page.jsx similarity index 92% rename from src/app/App.jsx rename to src/pages/index/+Page.jsx index f62c5e9..c02e311 100644 --- a/src/app/App.jsx +++ b/src/pages/index/+Page.jsx @@ -1,15 +1,14 @@ -import { Suspense, lazy } from 'react' +import Flash from '../../components/Flash' -import comma from '../assets/comma.svg' -import fastbootPorts from '../assets/fastboot-ports.svg' -import zadigCreateNewDevice from '../assets/zadig_create_new_device.png' -import zadigForm from '../assets/zadig_form.png' +import comma from '../../assets/comma.svg' +import fastbootPorts from '../../assets/fastboot-ports.svg' +import zadigCreateNewDevice from '../../assets/zadig_create_new_device.png' +import zadigForm from '../../assets/zadig_form.png' -const Flash = lazy(() => import('./Flash.client')); export default function App() { - const version = import.meta.env.VITE_PUBLIC_GIT_SHA || 'dev' - console.info(`flash.comma.ai version: ${version}`); + const version = import.meta?.env?.VITE_PUBLIC_GIT_SHA ?? 'dev' + console.info(`flash.comma.ai version: ${version}`) return (
@@ -149,9 +148,7 @@ export default function App() {
- - - +
diff --git a/src/app/App.test.jsx b/src/pages/index/Page.test.jsx similarity index 100% rename from src/app/App.test.jsx rename to src/pages/index/Page.test.jsx diff --git a/src/utils/fastboot.js b/src/utils/fastboot.js index 5142b4b..5171e5c 100644 --- a/src/utils/fastboot.js +++ b/src/utils/fastboot.js @@ -103,7 +103,7 @@ export function useFastboot() { /** @type {React.RefObject} */ const manifest = useRef(null) - const initializePromise = useRef(null); + const initializePromise = useRef(null) function setMessage(message = '') { if (message) console.info('[fastboot]', message) diff --git a/vite.config.js b/vite.config.js index e379ad4..8d0a0c1 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,26 +1,19 @@ -import { fileURLToPath, URL } from 'node:url'; +import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' -import tailwindcss from 'tailwindcss' -import autoprefixer from 'autoprefixer' +import vike from 'vike/plugin' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ react(), + vike({ + prerender: true, + }), ], - build: { - ssr: true, - rollupOptions: { - input: { - server: '/src/entry-server.jsx', - }, - }, - }, - css: { - postcss: { - plugins: [tailwindcss, autoprefixer], - }, + publicDir: 'public', + preview: { + port: 5173 }, resolve: { alias: [