rowiejs
v0.4.4
Published
Meta-framework React de nueva generación con SSR, SSG y CSR híbrido
Downloads
52
Maintainers
Readme
🚀 rowiejs
Meta-framework React de nueva generación con SSR, SSG y CSR híbrido
rowiejs es un meta-framework React moderno que combina la simplicidad de un SPA con el poder del Server-Side Rendering (SSR), Static Site Generation (SSG) y Client-Side Rendering (CSR). Diseñado para desarrolladores que buscan máxima productividad sin comprometer el rendimiento.
✨ Características Principales
🛣️ Enrutado Automático
- File-based routing basado en la estructura de carpetas
- Rutas dinámicas con parámetros
[id]y[slug] - Zero configuración - solo crea archivos y las rutas se generan automáticamente
- Navegación programática con hooks optimizados
🔍 SEO Real
- Meta tags dinámicos para cada página
- Open Graph y Twitter Cards automáticos
- Sitemap.xml generado automáticamente
- Canonical URLs y keywords configurables
- SSR/SSG para mejor indexación en motores de búsqueda
⚡ Múltiples Modos de Renderizado
- SSR (Server-Side Rendering): Renderizado en el servidor para mejor SEO
- SSG (Static Site Generation): Páginas estáticas para máximo rendimiento
- CSR (Client-Side Rendering): SPA tradicional con hot reload
- Híbrido: Combina diferentes modos según las necesidades
🎨 Developer Experience
- TypeScript nativo con tipado estricto
- Hot Module Replacement con Vite
- CLI intuitivo con comandos simples
- Templates predefinidos para proyectos comunes
- Zero configuración para empezar rápidamente
🚀 Instalación
Instalación Global
npm install -g rowiejsInstalación Local
npm install rowiejsVerificar Instalación
rowiejs --version📦 Crear un Nuevo Proyecto
rowiejs incluye un generador de proyectos con templates predefinidos:
# Crear proyecto básico
rowiejs create mi-app
# Crear blog
rowiejs create mi-blog --template blog
# Crear tienda online
rowiejs create mi-tienda --template ecommerce
# Crear en directorio específico
rowiejs create mi-app --directory /ruta/destinoTemplates Disponibles
| Template | Descripción | Uso Recomendado |
|----------|-------------|-----------------|
| basic | Aplicación básica con páginas de ejemplo | Proyectos generales, landing pages |
| blog | Blog con posts dinámicos y categorías | Blogs personales, sitios de noticias |
| ecommerce | Tienda online con productos y catálogo | Tiendas, marketplaces |
🏗️ Estructura del Proyecto
Después de crear un proyecto, tendrás esta estructura:
mi-app/
├── app/ # Páginas de la aplicación
│ ├── index.tsx # Página principal (/)
│ ├── about.tsx # Página about (/about)
│ ├── blog/ # Sección blog
│ │ ├── index.tsx # Lista de posts (/blog)
│ │ └── [slug].tsx # Post individual (/blog/:slug)
│ └── products/ # Sección productos
│ ├── index.tsx # Catálogo (/products)
│ └── [id].tsx # Producto individual (/products/:id)
├── public/ # Archivos estáticos
├── package.json # Dependencias y scripts
├── tsconfig.json # Configuración TypeScript
├── vite.config.ts # Configuración Vite
└── index.html # Template HTML base🛠️ Comandos CLI
Desarrollo
# Iniciar servidor de desarrollo
rowiejs dev
# Con opciones personalizadas
rowiejs dev --port 3000 --host localhost --app-dir appConstrucción
# Build para producción (SSG por defecto)
rowiejs build
# Build para SSR
rowiejs build --mode ssr
# Con directorios personalizados
rowiejs build --app-dir app --out-dir distProducción
# Iniciar servidor SSR en producción
rowiejs start
# Con configuración personalizada
rowiejs start --port 3000 --host 0.0.0.0 --dist-dir dist📝 Crear Páginas
Página Básica
Crea un archivo en la carpeta app/ y automáticamente se convierte en una ruta:
// app/contacto.tsx
import { useSEO } from 'rowiejs';
export default function Contacto() {
useSEO({
title: 'Contacto - Mi App',
description: 'Página de contacto de mi aplicación',
keywords: ['contacto', 'información', 'ayuda']
});
return (
<div>
<h1>Contacto</h1>
<p>Información de contacto...</p>
</div>
);
}Rutas Dinámicas
Para crear rutas con parámetros, usa corchetes en el nombre del archivo:
// app/blog/[slug].tsx
import { useSEO } from 'rowiejs';
interface PageProps {
params: { slug: string };
}
export default function BlogPost({ params }: PageProps) {
const { slug } = params;
useSEO({
title: `Post: ${slug} - Mi Blog`,
description: `Artículo sobre ${slug}`,
keywords: ['blog', 'artículo', slug]
});
return (
<div>
<h1>Post: {slug}</h1>
<p>Contenido del post...</p>
</div>
);
}Rutas Anidadas
Crea carpetas para organizar rutas:
// app/productos/categoria/[id].tsx
export default function Producto({ params }: { params: { id: string } }) {
return (
<div>
<h1>Producto {params.id}</h1>
</div>
);
}🔍 SEO y Meta Tags
rowiejs incluye un sistema completo de SEO con el hook useSEO:
import { useSEO } from 'rowiejs';
export default function MiPagina() {
useSEO({
title: 'Mi Página - Título SEO',
description: 'Descripción optimizada para motores de búsqueda',
keywords: ['palabra1', 'palabra2', 'palabra3'],
ogTitle: 'Título para redes sociales',
ogDescription: 'Descripción para compartir en redes sociales',
ogImage: 'https://mi-sitio.com/imagen-compartir.jpg',
twitterCard: 'summary_large_image',
canonical: 'https://mi-sitio.com/mi-pagina'
});
return <div>Contenido de la página</div>;
}Meta Tags Generados
El hook useSEO genera automáticamente:
<title>- Título de la página<meta name="description">- Descripción<meta name="keywords">- Palabras clave<meta property="og:title">- Open Graph título<meta property="og:description">- Open Graph descripción<meta property="og:image">- Open Graph imagen<meta name="twitter:card">- Twitter Card<link rel="canonical">- URL canónica
🎯 Modos de Renderizado
SSR (Server-Side Rendering)
Ideal para contenido dinámico y mejor SEO:
# Build para SSR
rowiejs build --mode ssr
# Iniciar servidor SSR
rowiejs startVentajas:
- ✅ SEO perfecto
- ✅ Contenido dinámico
- ✅ Tiempo de carga inicial rápido
- ✅ Compatible con APIs dinámicas
SSG (Static Site Generation)
Perfecto para sitios con contenido estático:
# Build para SSG (por defecto)
rowiejs build --mode ssgVentajas:
- ✅ Máximo rendimiento
- ✅ Hosting estático (CDN)
- ✅ SEO excelente
- ✅ Menor costo de servidor
CSR (Client-Side Rendering)
Para desarrollo y SPAs tradicionales:
# Desarrollo con hot reload
rowiejs devVentajas:
- ✅ Desarrollo rápido
- ✅ Hot reload
- ✅ Interactividad completa
- ✅ Fácil debugging
🧭 Navegación
Navegación con React Router
rowiejs usa React Router DOM internamente:
import { Link, useNavigate } from 'react-router-dom';
export default function Navegacion() {
const navigate = useNavigate();
return (
<nav>
<Link to="/">Inicio</Link>
<Link to="/about">Acerca de</Link>
<Link to="/blog">Blog</Link>
<button onClick={() => navigate('/contacto')}>
Ir a Contacto
</button>
</nav>
);
}Hook useAutoRouter
Accede a información de rutas:
import { useAutoRouter } from 'rowiejs';
export default function MiComponente() {
const { currentRoute, routes, params, searchParams } = useAutoRouter();
return (
<div>
<p>Ruta actual: {currentRoute?.path}</p>
<p>Parámetros: {JSON.stringify(params)}</p>
<p>Query params: {JSON.stringify(searchParams)}</p>
</div>
);
}🎨 Estilos y Assets
CSS Modules
// app/estilos.module.css
.titulo {
color: #2563eb;
font-size: 2rem;
}
// app/mi-pagina.tsx
import styles from './estilos.module.css';
export default function MiPagina() {
return <h1 className={styles.titulo}>Mi Título</h1>;
}Archivos Estáticos
Coloca archivos estáticos en la carpeta public/:
public/
├── favicon.ico
├── logo.png
└── images/
└── hero.jpgAccede a ellos desde las rutas:
<img src="/logo.png" alt="Logo" />
<img src="/images/hero.jpg" alt="Hero" />🔧 Configuración Avanzada
Vite Config
Personaliza la configuración de Vite:
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
host: true
},
build: {
outDir: 'dist',
sourcemap: true
}
});TypeScript Config
Configuración TypeScript optimizada:
{
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": ["app/**/*"],
"exclude": ["node_modules", "dist"]
}📦 Despliegue
Vercel (Recomendado)
- Conecta tu repositorio a Vercel
- Configura el build command:
rowiejs build - Configura el output directory:
dist - Despliega automáticamente
Netlify
- Conecta tu repositorio a Netlify
- Build command:
rowiejs build - Publish directory:
dist - Despliega
Servidor Propio (SSR)
# Build para SSR
rowiejs build --mode ssr
# Iniciar servidor
rowiejs start --port 3000 --host 0.0.0.0Docker
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "run", "start"]🧪 Testing
Configuración de Testing
npm install --save-dev vitest @testing-library/react @testing-library/jest-dom// vitest.config.ts
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
setupFiles: ['./src/test/setup.ts']
}
});Ejemplo de Test
// app/__tests__/mi-pagina.test.tsx
import { render, screen } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import MiPagina from '../mi-pagina';
test('renderiza la página correctamente', () => {
render(
<BrowserRouter>
<MiPagina />
</BrowserRouter>
);
expect(screen.getByText('Mi Título')).toBeInTheDocument();
});🚀 Ejemplos de Uso
Blog Personal
// app/blog/index.tsx
import { useSEO } from 'rowiejs';
import { Link } from 'react-router-dom';
const posts = [
{ id: 'primer-post', title: 'Mi Primer Post', date: '2024-01-15' },
{ id: 'segundo-post', title: 'Segundo Post', date: '2024-01-20' }
];
export default function BlogIndex() {
useSEO({
title: 'Blog - Mi Sitio',
description: 'Artículos y pensamientos sobre desarrollo web'
});
return (
<div>
<h1>Mi Blog</h1>
{posts.map(post => (
<article key={post.id}>
<h2>
<Link to={`/blog/${post.id}`}>{post.title}</Link>
</h2>
<time>{post.date}</time>
</article>
))}
</div>
);
}Tienda Online
// app/productos/[id].tsx
import { useSEO } from 'rowiejs';
interface ProductoProps {
params: { id: string };
}
export default function Producto({ params }: ProductoProps) {
const producto = {
id: params.id,
nombre: 'Producto Ejemplo',
precio: 99.99,
descripcion: 'Descripción del producto...'
};
useSEO({
title: `${producto.nombre} - Mi Tienda`,
description: producto.descripcion,
ogImage: `/images/productos/${producto.id}.jpg`
});
return (
<div>
<h1>{producto.nombre}</h1>
<p>{producto.descripcion}</p>
<p>Precio: ${producto.precio}</p>
<button>Agregar al Carrito</button>
</div>
);
}API Routes (Futuro)
// app/api/usuarios.ts
export async function GET() {
const usuarios = await fetchUsuarios();
return Response.json(usuarios);
}
export async function POST(request: Request) {
const data = await request.json();
const usuario = await crearUsuario(data);
return Response.json(usuario);
}🤝 Contribuir
¡Las contribuciones son bienvenidas! Por favor:
- Fork el proyecto
- Crea una rama para tu feature (
git checkout -b feature/AmazingFeature) - Commit tus cambios (
git commit -m 'Add some AmazingFeature') - Push a la rama (
git push origin feature/AmazingFeature) - Abre un Pull Request
Desarrollo Local
# Clonar el repositorio
git clone https://github.com/fabriciodev26/rowiejs.git
# Instalar dependencias
cd rowiejs
npm install
# Build del framework
npm run build-framework
# Probar localmente
npm link📚 Recursos Adicionales
🐛 Reportar Bugs
Si encuentras un bug, por favor:
- Verifica que no esté reportado en Issues
- Crea un nuevo issue con:
- Descripción detallada del problema
- Pasos para reproducir
- Versión de rowiejs
- Entorno (OS, Node.js, etc.)
📄 Licencia
Este proyecto está licenciado bajo la Licencia MIT - ver el archivo LICENSE para detalles.
🙏 Agradecimientos
- React - La biblioteca de UI
- Vite - El build tool
- React Router - El enrutador
- TypeScript - El tipado estático
Hecho con ❤️ por fabriciodev26
¿Te gusta rowiejs? ¡Dale una ⭐ en GitHub!
