UNPKG

vjsrouter

Version:

A modern, file-system based router for vanilla JavaScript with SSR support.

69 lines (55 loc) 2.79 kB
// File: src/server/index.js const path = require('path'); const fs = require('fs'); const express = require('express'); // The web server framework. const { VJSServerRouter } = require('./VJSServerRouter.cjs'); const { renderComponentTree, renderFullPage } = require('./renderer.cjs'); /** * Creates and configures an Express.js application for Server-Side Rendering with vjsrouter. * @param {Object} options - Configuration options. * @param {string} options.projectRoot - The absolute path to the root of the user's project. * @returns {express.Application} A fully configured Express app instance. */ function createVjsSsrServer(options) { const app = express(); // --- Robust Path Configuration --- // Use the provided projectRoot or default to the current working directory. const projectRoot = options.projectRoot || process.cwd(); const manifestPath = path.join(projectRoot, 'routes.json'); const staticAssetsPath = path.join(projectRoot); // Serve static files from the root const templatePath = path.join(projectRoot, 'index.html'); // --- 1. Initialize the Server-Side Router --- const serverRouter = new VJSServerRouter({ manifestPath }); // --- 2. Serve Static Assets --- // This middleware serves files like CSS, client-side JS, images, etc. // It's crucial that this comes *before* the SSR middleware. app.use(express.static(staticAssetsPath)); // --- 3. The Core SSR Middleware --- // This handles all other GET requests, assuming they are for pages. app.get('*', async (req, res) => { try { // --- A. Resolve the Route and Fetch Data --- const resolution = await serverRouter.resolve(req.path); // --- B. Render the Component Tree to an HTML string --- const { appHtml, initialData } = await renderComponentTree(projectRoot, resolution); // --- C. Read the HTML template --- const template = fs.readFileSync(templatePath, 'utf-8'); // --- D. Inject rendered HTML and data into the template --- const finalHtml = renderFullPage(template, appHtml, initialData); // --- E. Send the final HTML to the browser --- // We check if the route was a 404 to send the correct HTTP status code. if (resolution.route.path === '/404') { res.status(404).send(finalHtml); } else { res.status(200).send(finalHtml); } } catch (error) { // --- F. Robust Error Handling --- // If anything fails during the SSR process, log it and send a 500 error. console.error(`[SSR Middleware] Failed to render path ${req.path}:`, error); res.status(500).send('<h1>500 - Internal Server Error</h1><p>Something went wrong on our end. Please try again later.</p>'); } }); return app; } module.exports = { createVjsSsrServer };