@ressjs/vite-router
v0.5.1
Published
Express router factory for ress.js with automatic page detection, SSR and dynamic routes support
Readme
@ressjs/vite-router
Advanced Express router with dynamic routes, platform detection, and Server-Side Rendering (SSR) for RESS.js applications.
Installation
npm install @ressjs/vite-routerFeatures
- 🎯 Dynamic Routes: Next.js-style routing with
[param]syntax - 🎨 Platform Detection: Automatic device, OS, and WebView detection
- ⚡ SSR Support: Complete server-side rendering with proper hydration
- 📱 Smart Assets: Platform-specific CSS/JS bundle resolution
- 🔧 Middleware System: File-based middleware with execution order control
- 🔄 Development Mode: Hot reload with fast refresh and dev server
- 🚀 Production Ready: Optimized builds with manifest-based asset loading
- 📝 TypeScript: Full TypeScript support with comprehensive type definitions
Quick Start
Vite Configuration
Create a vite.config.ts file in your project root:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { getClientEntriesInput, getViteSSRInput } from '@ressjs/vite-router'
const isSSR = !!process.env.VITE_SSR_BUILD
export default defineConfig(async () => ({
plugins: [react()],
server: {
watch: {
ignored: ['**/dist/.entries/**'] // Ignore generated entries
}
},
build: {
manifest: true,
outDir: isSSR ? 'dist/server' : 'dist/client',
rollupOptions: {
input: isSSR
? getViteSSRInput() // SSR entry point
: await getClientEntriesInput(), // Auto-generated client entries
},
ssr: isSSR,
},
}))Important: The router automatically generates entry files for each page/platform combination in dist/.entries/. These are used by Vite for building client bundles.
Basic Setup
import express from 'express'
import { createViteRouter } from '@ressjs/vite-router'
const app = express()
const router = createViteRouter({
enablePlatformDetection: true,
isProduction: process.env.NODE_ENV === 'production'
})
app.use('/', router)
app.listen(3000, () => console.log('Server running on port 3000'))Development Server Setup
Create a server.js file for development:
import { createServer } from 'vite'
import { createViteRouter } from '@ressjs/vite-router'
import express from 'express'
async function createDevServer() {
const app = express()
// Create Vite server in middleware mode
const vite = await createServer({
server: { middlewareMode: true },
appType: 'custom'
})
// Use vite's connect instance as middleware
app.use(vite.ssrLoadModule)
// Create router with Vite instance
const router = createViteRouter({
vite,
enablePlatformDetection: true,
isProduction: false
})
app.use('/', router)
app.listen(3000, () => console.log('Dev server running on port 3000'))
}
createDevServer()Package.json Scripts
Add these scripts to your package.json:
{
"scripts": {
"dev": "node server.js",
"build": "npm run build:client && npm run build:server",
"build:client": "vite build",
"build:server": "VITE_SSR_BUILD=true vite build",
"preview": "NODE_ENV=production node server.js",
"type-check": "tsc --noEmit"
},
"dependencies": {
"@ressjs/vite-router": "^0.5.0",
"express": "^4.18.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"vite": "^5.0.0"
},
"devDependencies": {
"@types/express": "^4.17.0",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@vitejs/plugin-react": "^4.0.0",
"typescript": "^5.0.0"
}
}TypeScript Backend Integration
For full-stack TypeScript projects with backend APIs, use this enhanced configuration:
{
"name": "my-fullstack-app",
"type": "module",
"scripts": {
"dev": "PORT=3000 vite-node server.ts",
"build": "npm run build:client && npm run build:server",
"build:client": "vite build --outDir dist/client",
"build:server": "cross-env VITE_SSR_BUILD=1 vite build --ssr --outDir dist/server",
"preview": "cross-env NODE_ENV=production PORT=3000 tsx server.ts",
"start": "npm run build && npm run preview"
},
"dependencies": {
"@ressjs/vite-router": "^0.5.0",
"cross-env": "^7.0.3",
"express": "^4.18.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"tsx": "^4.7.1",
"typescript": "^5.0.0",
"vite": "^5.0.0"
},
"devDependencies": {
"@types/express": "^4.17.0",
"@types/node": "^22.0.0",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@vitejs/plugin-react": "^4.0.0",
"vite-node": "^3.2.0"
}
}Key differences for TypeScript backends:
vite-node server.ts: Direct TypeScript execution in developmenttsx server.ts: Fast TypeScript runner for productiontype: "module": Enable ES modules in Node.jscross-env: Cross-platform environment variables
When to use this setup:
- Building APIs alongside your frontend
- Need database connections, authentication, file uploads
- Want full TypeScript integration across the stack
- Require additional Express middleware and routes
Key Points:
VITE_SSR_BUILD=true: Environment variable that tells Vite config to build for SSR- Separate builds: Client and server are built separately with different entry points
- Auto-generated entries:
getClientEntriesInput()discovers all page/platform combinations
Auto Server (WIP)
import { createAutoViteServer } from '@ressjs/vite-router'
// Automatically configures Vite dev server with SSR (Work In Progress)
const { start } = await createAutoViteServer({
port: 3000,
enablePlatformDetection: true
})
start()🎯 Dynamic Routes
Create pages with parameters using Next.js-style bracket syntax:
File Structure
app/pages/
├── index.tsx # / route
├── about.tsx # /about route
├── users/
│ ├── index.tsx # /users route
│ └── [id].tsx # /users/:id route
├── products/
│ ├── [category].tsx # /products/:category route
│ └── [category]/
│ └── [id].tsx # /products/:category/:id route
└── blog/
└── [...slug].tsx # /blog/* route (coming soon)Route Examples
| File | Route | Express Route | URL Example |
|------|-------|---------------|-------------|
| users/[id].tsx | /users/[id] | /users/:id | /users/123 |
| products/[category]/[id].tsx | /products/[category]/[id] | /products/:category/:id | /products/phones/iphone |
| photocard/[photoId].tsx | /photocard/[photoId] | /photocard/:photoId | /photocard/abc123xyz |
Accessing Parameters
// app/pages/users/[id].tsx
export default function UserPage({ id, user }) {
return (
<div>
<h1>User {id}</h1>
<p>Name: {user.name}</p>
</div>
)
}
export async function getServerSideProps(req, res) {
const { id } = req.params // Access route parameters
// Fetch user data
const user = await fetchUser(id)
return {
props: { id, user }
}
}Dynamic Route Styles
Dynamic routes support platform-specific styles:
app/pages/products/[id].tsx # Product page component
app/pages/products/[id].scss # Desktop styles
app/pages/products/[id].mobile.scss # Mobile styles
app/pages/products/[id].webview.scss # WebView styles🔧 Middleware System
Important: Dynamic routes [param].tsx do NOT support dedicated middleware files. Use page-level or directory-level middleware instead.
Middleware Execution Order
app/pages/
├── middlewares.ts # --> Executes 1st (global)
├── products/
│ ├── middlewares.ts # --> Executes 2nd (directory-level)
│ ├── index.tsx
│ ├── index.middlewares.ts # --> Executes 3rd (page-specific)
│ └── [id].tsx # --> No middleware support for dynamic routes
├── users/
│ ├── [id].tsx # --> Uses directory and global middleware only
│ └── middlewares.ts # --> Executes for all /users/* routes
└── checkout/
├── middlewares.ts # --> Executes 2nd for /checkout/*
├── step1.tsx
├── step1.middlewares.ts # --> Executes 3rd for /checkout/step1
├── step2.tsx
└── step2.middlewares.ts # --> Executes 3rd for /checkout/step2Middleware Types
1. Global Middleware
// app/pages/middlewares.ts --> Executes 1st for ALL routes
export default function globalMiddleware(req, res, next) {
console.log('Global middleware for:', req.url)
req.startTime = Date.now()
next()
}2. Directory Middleware
// app/pages/products/middlewares.ts --> Executes 2nd for /products/*
export default function productsMiddleware(req, res, next) {
console.log('Products middleware for:', req.url)
req.section = 'products'
next()
}3. Page-Specific Middleware
// app/pages/products/index.middlewares.ts --> Executes 3rd for /products only
export default function productListMiddleware(req, res, next) {
console.log('Product list middleware')
req.page = 'product-list'
next()
}❌ Not Supported for Dynamic Routes
// ❌ app/pages/products/[id].middlewares.ts - NOT supported
// Dynamic routes cannot have dedicated middleware filesComplete Execution Flow Example
For URL /products/123:
- Global:
app/pages/middlewares.ts(if exists) - Directory:
app/pages/products/middlewares.ts(if exists) - Page: Built-in
getServerSidePropsfrom[id].tsx - Render: Component render and HTML generation
📱 Platform Detection
The router automatically detects and serves platform-specific assets:
Detection Capabilities
- Device Type:
phone,tablet,desktop - Operating System:
ios,android,windows,macos,linux - Environment:
webview,web,native - Category:
webview.android,webview.ios,mobile, etc.
Platform Headers (React Native)
React Native clients should send these headers:
{
'x-ressjs-platform': 'webview', // Required
'x-ressjs-os': 'ios', // Required
'x-ressjs-device': 'phone', // Required
'x-ressjs-version': Platform.Version, // Optional
'x-ressjs-app-version': '1.0.0' // Optional
}Asset Resolution Priority
For a page like app/pages/home/index.tsx:
- Device + OS Specific:
index.phone.ios.scss - Device Specific:
index.phone.scss - Category Specific:
index.mobile.scss - WebView Specific:
index.webview.scss - Base Fallback:
index.scss
Platform CSS Examples
app/pages/home/
├── index.tsx # React component
├── index.scss # Desktop/base styles
├── index.mobile.scss # Phone + tablet
├── index.phone.scss # Phone only
├── index.tablet.scss # Tablet only
├── index.webview.scss # All WebView
├── index.webview.ios.scss # iOS WebView
├── index.webview.android.scss # Android WebView
└── index.desktop.linux.scss # Linux desktop🎨 getServerSideProps
Every page can export a getServerSideProps function for server-side data fetching:
export async function getServerSideProps(req, res) {
// Access route parameters (for dynamic routes)
const { id, category } = req.params
// Access query parameters
const { search, filter } = req.query
// Access request headers
const userAgent = req.headers['user-agent']
// Return props for the component
return {
props: {
id,
data: await fetchData(id),
timestamp: new Date().toISOString()
},
// Optional: HTML modifications
title: `Product ${id}`,
html: {
head: {
title: `Custom Title`,
extraTags: ['<meta name="description" content="...">']
}
}
}
}🚀 API Reference
createViteRouter(options)
interface ViteRouterOptions {
enablePlatformDetection?: boolean // Enable platform detection (default: true)
vite?: any // Vite dev server instance
manifest?: any // Production manifest
templateHtml?: string // HTML template
isProduction?: boolean // Production mode
renderFunction?: (options: { // Custom render function
url: string
platform: string
req: any
}) => Promise<string>
}createAutoViteServer(options)
interface AutoViteServerOptions {
port?: number // Server port (default: 5173)
base?: string // Base path (default: '/')
enablePlatformDetection?: boolean // Enable platform detection (default: true)
}Utility Functions
import {
getPages,
listDetectedPages,
convertRouteToExpress
} from '@ressjs/vite-router'
// Get all discovered pages with route info
const pages = getPages()
// [{ route: '/users/[id]', expressRoute: '/users/:id', file: '...', abs: '...' }]
// Convert Next.js route to Express route
const expressRoute = convertRouteToExpress('/users/[id]') // '/users/:id'🔧 Production Build
Build Process
# 1. Build client assets
vite build --outDir dist/client
# 2. Build server bundle
vite build --ssr --outDir dist/server
# 3. Start production server
NODE_ENV=production node server.jsExample Production Server
import express from 'express'
import { createViteRouter } from '@ressjs/vite-router'
const app = express()
// Serve static assets
app.use('/assets', express.static('dist/client/assets'))
// Create router with production settings
const router = createViteRouter({
isProduction: true,
enablePlatformDetection: true
})
app.use('/', router)
app.listen(3000)🐛 Troubleshooting
Dynamic Route Not Working
- Check file naming: Use
[param].tsx, not{param}.tsx - Verify parameters: Access via
req.params.paramingetServerSideProps - Build order: Run
npm run buildafter adding new dynamic routes
Middleware Not Executing
- File naming: Use
middlewares.ts(plural) orpage.middlewares.ts - Dynamic routes: Don't create
[param].middlewares.ts- not supported - Export: Use
export default functionformat
Platform Detection Issues
- Headers: Ensure React Native sends required
x-ressjs-*headers - CSS files: Create platform-specific CSS files if needed
- Case sensitivity: Use lowercase for OS names (
ios,android)
📄 License
MIT
para grabar la camara y la pantalla al mismo tiempo me conviene obs? pense que la grabacion nativa de mac ya era suficientemente buena, pero creo que no soporta camara
ayudame a organizar los videos de la primer temporada, pero no los voy a organizar como dijiste, voy a hacer lo que se me cante
10 videos para algoritmos
10 videos para estructuras de datos
que es programar? explicar temas basicos, que es un programa, que es un proceso, que es un programador, cual es el trabajo del programador, cuales son los diferentes roles que puede tomar (desarrollo de apis backend, frontend, electronicos), cual es la oferta laboral (esta raro el mercado por todo el tema de la IA, explicar que no hay tanta oferta laboral como antes, pero que sigue siendo una profesion bien pagada), eso para lo basico. Para la parte avanzada explicar que es un compilador, el proceso de compilar, entrada proceso y salida y donde se almacenan los programas durante el apagado (disco) y durante la ejecucion (ram), explicar que existe algo llamado instruction pointer, que va ejecutando linea a linea mientras las paginas del proceso esten en ram, en caso contrario durante la ejecuccion bajara hasta el disco a buscar lo que le falta. Ayudame a ser mas preciso con estos temas
interfaces para programar (IDE) y herramientas necesarias. explicacion de como instalar vs code, explicar que al principio no van a hacer desarrollos con interfaces porque estan aprendiendo, dar un ejemplo claro de como ingresar datos y mostrarlos por pantalla.
para el avanzado: explicar que es un CLI y su evolucion/relacion con las interfaces graficas, contar que hay muchos IDEs pagos como cursor
que es una variable, explicar con dibujitos el concepto, relacionandolo con un espacio fisico, un lugar que se puede reutilizar, quiero dar un ejemplo como de una caja a la que le meto y le saco cosas. Es importante que le pongan nombres claros a las variables. Este video probablemente lo haga en typescript para explicar tambien tipos de datos. Para la parte avanzada quiero hablar de inferencia de tipos, lenguajes tipados y no tipados. dar ejemplos con java, python, js, ts
que son las estructuras condicionales, explicacion if y else como caminos tipo izq y derecha, explicacion de switch como un caso de multiples caminos o valores. para la parte avanzada explicar ternarios, variables de tipo booleanas, porque sirve guardar condiciones en variables (para poder leer mejor el codigo). Explicar como escribirlo para que sea legible,
explicacion de bucles, explicar el while, explicar que el for es un while con esteroides, explicar como se va juntando con los temas anteriores, hacer un ejemplo sencillo donde por ejemplo se cuente cuantas personas son mayores de edad. Para la parte avanzada, explicar que existen las funciones lambda, unas funciones que facilitan el uso y gestion de bucles, que estan relacionados con el POO, que de todas formas mas adelante intentaremos sacar una serie
para grabar la camara y la pantalla al mismo tiempo me conviene obs? pense que la grabacion nativa de mac ya era suficientemente buena, pero creo que no soporta camara
ayudame a organizar los videos de la primer temporada, pero no los voy a organizar como dijiste, voy a hacer lo que se me cante
10 videos para algoritmos
10 videos para estructuras de datos
para grabar la camara y la pantalla al mismo tiempo me conviene obs? pense que la grabacion nativa de mac ya era suficientemente buena, pero creo que no soporta camara
ayudame a organizar los videos de la primer temporada, pero no los voy a organizar como dijiste, voy a hacer lo que se me cante
10 videos para algoritmos
10 videos para estructuras de datos
introduccion de como ver y estudiar con este curso (lo hare al final, despues de tener todos los videos hechos, tambien explicare que para cada video dejare una serie de 10 ejercicios que van subiendo de dificultad). Dejar en claro que estudiar esto es como la matematica, la unica forma de aprenderlo es sentar el culo en la silla y ponerse a jugar. Explicar si te conviene usar la IA para algo
que es programar? explicar temas basicos, que es un programa, que es un proceso, que es un programador, cual es el trabajo del programador, cuales son los diferentes roles que puede tomar (desarrollo de apis backend, frontend, electronicos), cual es la oferta laboral (esta raro el mercado por todo el tema de la IA, explicar que no hay tanta oferta laboral como antes, pero que sigue siendo una profesion bien pagada), eso para lo basico. Para la parte avanzada explicar que es un compilador, el proceso de compilar, entrada proceso y salida y donde se almacenan los programas durante el apagado (disco) y durante la ejecucion (ram), explicar que existe algo llamado instruction pointer, que va ejecutando linea a linea mientras las paginas del proceso esten en ram, en caso contrario durante la ejecuccion bajara hasta el disco a buscar lo que le falta. Ayudame a ser mas preciso con estos temas.
interfaces para programar (IDE) y herramientas necesarias. explicacion de como instalar vs code, explicar que al principio no van a hacer desarrollos con interfaces porque estan aprendiendo, dar un ejemplo claro de como ingresar datos y mostrarlos por pantalla. Explicar que existen libs, que es codigo creado por otras personas.
para el avanzado: explicar que es un CLI y su evolucion/relacion con las interfaces graficas, contar que hay muchos IDEs pagos como cursor
que es una variable, explicar con dibujitos el concepto, relacionandolo con un espacio fisico, un lugar que se puede reutilizar, quiero dar un ejemplo como de una caja a la que le meto y le saco cosas. Es importante que le pongan nombres claros a las variables. Este video probablemente lo haga en typescript para explicar tambien tipos de datos. Para la parte avanzada quiero hablar de inferencia de tipos, lenguajes tipados y no tipados. dar ejemplos con java, python, js, ts
que son las estructuras condicionales, explicacion if y else como caminos tipo izq y derecha, explicacion de switch como un caso de multiples caminos o valores. para la parte avanzada explicar ternarios, variables de tipo booleanas, porque sirve guardar condiciones en variables (para poder leer mejor el codigo). Explicar como escribirlo para que sea legible,
explicacion de bucles, explicar el while, explicar que el for es un while con esteroides, explicar como se va juntando con los temas anteriores, hacer un ejemplo sencillo donde por ejemplo se cuente cuantas personas son mayores de edad. Para la parte avanzada, explicar que existen las funciones lambda, unas funciones que facilitan el uso y gestion de bucles, que estan relacionados con el POO, que de todas formas mas adelante intentaremos sacar una serie. Shortcircuits en js, orden de precedencia, lazy evaluation
explicar que es una funcion, explicar el concepto de entrada => proceso => salida
explicar su relacion con la matematica, explicar que es una firma, que existen dos tipos de funciones (las que realizan calculos y las que modifican valores, esto no es una certeza, es solo algo que digo por mi experiencia, no esta bien mezclar los objetivos de las funciones). Para el avanzado: explicar "pureza"? creo que ese era un nombre que se le daba (hay un concepto que decia que ante mismos valores de entrada deberia dar el mismo resultado), efecto de lado y si se te ocurre algun bocadillo mas para temas mas bien relacionados a programacion funcional viene bien, o incluso hablar de haskell y que existe este paradigma
recursividad, solo lo basico, decir que es una funcion que se llama a si misma, pero que no voy a profundizar demasiado porque lo veremos mas adelante luego de ver un poco mas de estructuras de datos. Compararlo con bucles, decirles que todos los ejercicios planteados anteriormente con bucles pueden resolverse en su lugar con una funcion (espero xd, sino armare una guia nueva). Para el avanzado, explicar que cada llamado consume memoria ram de tipo stack, que puede llevar a un stack overflow si no se controla.
integrar conocimientos, ejercicios relacionados a todo lo anterior
punteros
explicar que son las estructuras de datos (help, no se como explicarlo xd)
explicar que es un vector, que son posiciones de memoria contiguas en el stack, ejemplo de como recorrerlo o cargarlo usando un for. Para el avanzado mencionar que en C existe una funcion llamada scanf, que es insegura porque permite avanzar a mas partes de la ram y conseguir el valor de las variables dentro del stack, tambien si quiero mencionar que las variables se intentan asignar con un tamanio equivalente a la palabra del procesador (4 bytes, corrigeme si esta mal)
como ordenar un vector utilizando bubble sort o algo burbuja. Para el avanzado mencionar todos los algoritmos de recorrido y mencionar que es la complejidad algoritmica y mostrar cuanto miden
matrices. explicar que en el dia a dia no sirven tanto, pero en un futuro tal vez si te dedicas a la IA te sirvan, pero no lo tengo muy claro, explicar que las matrices cumplen muchas propiedades matematicas que se ven en algebra y matematicas discretas y que se pueden traspolar al codigo, asi quedo como un crack
mas ejemplos de matrices, resolver ejercicios
estructuras de datos "personales", me refiero a esos lenguajes tipo c o golang que permiten la palabre struct, tal vez convenga explicar el concepto de entidad en este video, que entiendan que es una representacion computacional de algo que existe. Explicar que estas structs se convierten en un nuevo tipo de dato y para la parte avanzada no se me ocurre nada, help
listas, compararlas con un vector, explicar que las listas pueden ser de muchos tipos de datos, listas enlazadas. Para el avanzado explicar algoritmos de ordenamiento de listas y su consumo de memoria, explica que a diferencia de los vectores no se almacenan en el stack sino en el heap
el queridisimo hashmap o mapa, explica sencillo en js como funciona, que produce accesos directos a memoria, que usa una cosa llamada funcion de hash, que suele venir con el lenguaje en una lib. Es una de las estructuras mas utilizada para resolver problemas tipicos (ayudame con ejemplos please). Para el avanzado, explicar como curiosidad que el switch es mas rapido que el if, porque internamente en ensamblador utiliza una cosa parecida a una tabla de hash.
integrarlo todo
despedida y cual deberia ser tu roadmap para seguir aprendiendo
