@ressjs/vite-router 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +221 -0
- package/dist/entry-generator.d.ts +34 -0
- package/dist/entry-generator.d.ts.map +1 -0
- package/dist/entry-generator.js +113 -0
- package/dist/entry-generator.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/page-detector.d.ts +44 -0
- package/dist/page-detector.d.ts.map +1 -0
- package/dist/page-detector.js +92 -0
- package/dist/page-detector.js.map +1 -0
- package/dist/router-factory.d.ts +58 -0
- package/dist/router-factory.d.ts.map +1 -0
- package/dist/router-factory.js +153 -0
- package/dist/router-factory.js.map +1 -0
- package/dist/simple-router.d.ts +44 -0
- package/dist/simple-router.d.ts.map +1 -0
- package/dist/simple-router.js +341 -0
- package/dist/simple-router.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 gabrielspisso
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# @ressjs/vite-router
|
|
2
|
+
|
|
3
|
+
Express router factory para SSR automático con detección de páginas y soporte multi-platform.
|
|
4
|
+
|
|
5
|
+
## Características
|
|
6
|
+
|
|
7
|
+
- 🚀 **Detección automática de páginas** - Escanea `app/pages/` y crea rutas automáticamente
|
|
8
|
+
- 📱 **Soporte multi-platform** - Detecta dispositivos móviles y carga estilos específicos
|
|
9
|
+
- ⚡ **SSR integrado** - Server-Side Rendering usando `@ressjs/core`
|
|
10
|
+
- 🎯 **Entry clients dinámicos** - Genera entry points específicos por platform
|
|
11
|
+
- 🛠️ **Zero-config** - Funciona out-of-the-box con configuración mínima
|
|
12
|
+
|
|
13
|
+
## Instalación
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @ressjs/vite-router
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Uso Básico
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
import express from 'express'
|
|
23
|
+
import { createViteRouter } from '@ressjs/vite-router'
|
|
24
|
+
|
|
25
|
+
const app = express()
|
|
26
|
+
|
|
27
|
+
// Crear router automático
|
|
28
|
+
const viteRouter = createViteRouter({
|
|
29
|
+
pagesDir: 'app/pages',
|
|
30
|
+
outputDir: 'dist/.entries',
|
|
31
|
+
enableSSR: true,
|
|
32
|
+
enablePlatformDetection: true
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
app.use('/', viteRouter)
|
|
36
|
+
app.listen(3000)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Uso Avanzado
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
import { RouterFactory } from '@ressjs/vite-router'
|
|
43
|
+
|
|
44
|
+
const factory = new RouterFactory({
|
|
45
|
+
pagesDir: 'app/pages',
|
|
46
|
+
outputDir: 'temp',
|
|
47
|
+
enableSSR: true,
|
|
48
|
+
enablePlatformDetection: true,
|
|
49
|
+
staticDir: 'public'
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
// Inicializar antes de usar
|
|
53
|
+
await factory.initialize()
|
|
54
|
+
|
|
55
|
+
const router = factory.createRouter()
|
|
56
|
+
app.use('/', router)
|
|
57
|
+
|
|
58
|
+
// Limpiar al finalizar
|
|
59
|
+
process.on('exit', () => {
|
|
60
|
+
factory.cleanup()
|
|
61
|
+
})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Detección de Páginas
|
|
65
|
+
|
|
66
|
+
El router automáticamente detecta páginas en la estructura:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
app/pages/
|
|
70
|
+
├── index.tsx -> ruta: /
|
|
71
|
+
├── about.tsx -> ruta: /about
|
|
72
|
+
├── products/
|
|
73
|
+
│ ├── index.tsx -> ruta: /products
|
|
74
|
+
│ └── [id].tsx -> ruta: /products/:id
|
|
75
|
+
└── blog/
|
|
76
|
+
└── post.tsx -> ruta: /blog/post
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Soporte Multi-Platform
|
|
80
|
+
|
|
81
|
+
### Estilos específicos por platform
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
app/pages/home/
|
|
85
|
+
├── index.tsx
|
|
86
|
+
├── index.scss -> estilos generales
|
|
87
|
+
├── index.mobile.scss -> solo móvil
|
|
88
|
+
└── index.desktop.scss -> solo desktop
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Detección automática
|
|
92
|
+
|
|
93
|
+
El router detecta el device usando el User-Agent y carga estilos específicos:
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
// En el cliente se añade automáticamente:
|
|
97
|
+
document.documentElement.classList.add('mobile') // o 'desktop'
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## API
|
|
101
|
+
|
|
102
|
+
### `createViteRouter(options)`
|
|
103
|
+
|
|
104
|
+
Crea un Express Router configurado automáticamente.
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
interface RouterFactoryOptions {
|
|
108
|
+
pagesDir: string // Directorio de páginas
|
|
109
|
+
outputDir?: string // Directorio para entries generados
|
|
110
|
+
enableSSR?: boolean // Habilitar SSR (default: true)
|
|
111
|
+
enablePlatformDetection?: boolean // Detección de platform (default: true)
|
|
112
|
+
staticDir?: string // Directorio de archivos estáticos
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `createInitializedViteRouter(options)`
|
|
117
|
+
|
|
118
|
+
Versión async que inicializa automáticamente el router.
|
|
119
|
+
|
|
120
|
+
### `RouterFactory`
|
|
121
|
+
|
|
122
|
+
Clase para control completo del router.
|
|
123
|
+
|
|
124
|
+
#### Métodos
|
|
125
|
+
|
|
126
|
+
- `initialize()` - Genera entries iniciales
|
|
127
|
+
- `createRouter()` - Crea el Express Router
|
|
128
|
+
- `cleanup()` - Limpia archivos temporales
|
|
129
|
+
|
|
130
|
+
### `PageDetector`
|
|
131
|
+
|
|
132
|
+
Utilidad para detectar páginas automáticamente.
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
import { PageDetector } from '@ressjs/vite-router'
|
|
136
|
+
|
|
137
|
+
const detector = new PageDetector({
|
|
138
|
+
pagesDir: 'app/pages'
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
const pages = await detector.getDetectedPages()
|
|
142
|
+
const match = detector.matchRoute('/products/123', pages)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### `EntryGenerator`
|
|
146
|
+
|
|
147
|
+
Generador de entry clients dinámicos.
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
import { EntryGenerator } from '@ressjs/vite-router'
|
|
151
|
+
|
|
152
|
+
const generator = new EntryGenerator({
|
|
153
|
+
pagesDir: 'app/pages',
|
|
154
|
+
outputDir: 'dist/.entries'
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
const platform = generator.detectPlatformFromRequest(req)
|
|
158
|
+
const entry = await generator.generatePlatformSpecificEntry(
|
|
159
|
+
'/products',
|
|
160
|
+
platform,
|
|
161
|
+
pages
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Integración con Vite
|
|
166
|
+
|
|
167
|
+
Ejemplo completo con Vite development server:
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
import fs from 'node:fs/promises'
|
|
171
|
+
import express from 'express'
|
|
172
|
+
import { createInitializedViteRouter } from '@ressjs/vite-router'
|
|
173
|
+
|
|
174
|
+
const isProduction = process.env.NODE_ENV === 'production'
|
|
175
|
+
const app = express()
|
|
176
|
+
|
|
177
|
+
let vite
|
|
178
|
+
if (!isProduction) {
|
|
179
|
+
const { createServer } = await import('vite')
|
|
180
|
+
vite = await createServer({
|
|
181
|
+
server: { middlewareMode: true },
|
|
182
|
+
appType: 'custom'
|
|
183
|
+
})
|
|
184
|
+
app.use(vite.middlewares)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Router automático con SSR
|
|
188
|
+
const viteRouter = await createInitializedViteRouter({
|
|
189
|
+
pagesDir: 'app/pages',
|
|
190
|
+
enableSSR: true,
|
|
191
|
+
enablePlatformDetection: true
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
app.use('/', viteRouter)
|
|
195
|
+
app.listen(3000)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Middleware Stack
|
|
199
|
+
|
|
200
|
+
El router crea automáticamente el siguiente stack de middleware:
|
|
201
|
+
|
|
202
|
+
1. **Page Detection** - Detecta páginas y prepara contexto
|
|
203
|
+
2. **Platform Detection** - Detecta dispositivo (móvil/desktop)
|
|
204
|
+
3. **Entry Generation** - Genera entry client específico
|
|
205
|
+
4. **SSR Rendering** - Renderiza servidor-side con React
|
|
206
|
+
5. **Static Files** - Fallback para archivos estáticos
|
|
207
|
+
|
|
208
|
+
## Tipos TypeScript
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
import type {
|
|
212
|
+
RouterFactoryOptions,
|
|
213
|
+
RouteContext,
|
|
214
|
+
PageRouterInfo,
|
|
215
|
+
EntryGeneratorOptions
|
|
216
|
+
} from '@ressjs/vite-router'
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Ejemplos
|
|
220
|
+
|
|
221
|
+
Ver `/examples/basic-ssr/` para un ejemplo completo de uso.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PageInfo } from '@ressjs/core';
|
|
2
|
+
import { Request as ExpressRequest } from 'express';
|
|
3
|
+
export interface EntryGeneratorOptions {
|
|
4
|
+
pagesDir: string;
|
|
5
|
+
outputDir?: string;
|
|
6
|
+
platform?: 'desktop' | 'mobile';
|
|
7
|
+
}
|
|
8
|
+
export declare class EntryGenerator {
|
|
9
|
+
private options;
|
|
10
|
+
constructor(options: EntryGeneratorOptions);
|
|
11
|
+
/**
|
|
12
|
+
* Genera entry-client dinámicos para las páginas detectadas
|
|
13
|
+
*/
|
|
14
|
+
generateDynamicEntries(): Promise<string[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Detecta el platform basado en el user-agent de la request
|
|
17
|
+
*/
|
|
18
|
+
detectPlatformFromRequest(req: ExpressRequest): 'desktop' | 'mobile';
|
|
19
|
+
/**
|
|
20
|
+
* Genera entry específico para un platform
|
|
21
|
+
*/
|
|
22
|
+
generatePlatformSpecificEntry(pageRoute: string, platform: 'desktop' | 'mobile', pages: PageInfo[]): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* Escribe entry files al filesystem
|
|
25
|
+
*/
|
|
26
|
+
writeEntryFiles(entries: {
|
|
27
|
+
[key: string]: string;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Limpia archivos temporales generados
|
|
31
|
+
*/
|
|
32
|
+
cleanup(): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=entry-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-generator.d.ts","sourceRoot":"","sources":["../src/entry-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,SAAS,CAAA;AAEnD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;CAChC;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAiC;gBAEpC,OAAO,EAAE,qBAAqB;IAQ1C;;OAEG;IACG,sBAAsB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIjD;;OAEG;IACH,yBAAyB,CAAC,GAAG,EAAE,cAAc,GAAG,SAAS,GAAG,QAAQ;IAUpE;;OAEG;IACG,6BAA6B,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,SAAS,GAAG,QAAQ,EAC9B,KAAK,EAAE,QAAQ,EAAE,GAChB,OAAO,CAAC,MAAM,CAAC;IAuElB;;OAEG;IACG,eAAe,CAAC,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxE;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ/B"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { generateTempEntries } from '@ressjs/core';
|
|
2
|
+
export class EntryGenerator {
|
|
3
|
+
constructor(options) {
|
|
4
|
+
this.options = {
|
|
5
|
+
outputDir: 'temp',
|
|
6
|
+
platform: 'desktop',
|
|
7
|
+
...options
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Genera entry-client dinámicos para las páginas detectadas
|
|
12
|
+
*/
|
|
13
|
+
async generateDynamicEntries() {
|
|
14
|
+
return generateTempEntries(this.options.outputDir);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Detecta el platform basado en el user-agent de la request
|
|
18
|
+
*/
|
|
19
|
+
detectPlatformFromRequest(req) {
|
|
20
|
+
const userAgent = req.headers['user-agent']?.toLowerCase() || '';
|
|
21
|
+
// Simple mobile detection
|
|
22
|
+
const mobileKeywords = ['mobile', 'android', 'iphone', 'ipad', 'blackberry', 'windows phone'];
|
|
23
|
+
const isMobile = mobileKeywords.some(keyword => userAgent.includes(keyword));
|
|
24
|
+
return isMobile ? 'mobile' : 'desktop';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Genera entry específico para un platform
|
|
28
|
+
*/
|
|
29
|
+
async generatePlatformSpecificEntry(pageRoute, platform, pages) {
|
|
30
|
+
const page = pages.find(p => p.route === pageRoute);
|
|
31
|
+
if (!page) {
|
|
32
|
+
throw new Error(`Page ${pageRoute} not found`);
|
|
33
|
+
}
|
|
34
|
+
// Detectar archivos de estilos relacionados con la página
|
|
35
|
+
const fs = await import('fs/promises');
|
|
36
|
+
const path = await import('path');
|
|
37
|
+
const pageDir = path.dirname(page.file);
|
|
38
|
+
const baseName = path.basename(page.file, path.extname(page.file));
|
|
39
|
+
// Buscar archivos de estilos
|
|
40
|
+
const possibleStyles = [
|
|
41
|
+
path.join(pageDir, `${baseName}.scss`),
|
|
42
|
+
path.join(pageDir, `${baseName}.css`),
|
|
43
|
+
path.join(pageDir, `${baseName}.${platform}.scss`),
|
|
44
|
+
path.join(pageDir, `${baseName}.${platform}.css`),
|
|
45
|
+
path.join(pageDir, 'index.scss'),
|
|
46
|
+
path.join(pageDir, 'index.css'),
|
|
47
|
+
path.join(pageDir, `index.${platform}.scss`),
|
|
48
|
+
path.join(pageDir, `index.${platform}.css`)
|
|
49
|
+
];
|
|
50
|
+
const existingStyles = [];
|
|
51
|
+
for (const stylePath of possibleStyles) {
|
|
52
|
+
try {
|
|
53
|
+
await fs.access(stylePath);
|
|
54
|
+
existingStyles.push(stylePath);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Archivo no existe, continuar
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Separar estilos generales de platform-specific
|
|
61
|
+
const generalStyles = existingStyles.filter(style => !style.includes(`.${platform}.`) &&
|
|
62
|
+
!style.includes('.mobile.') &&
|
|
63
|
+
!style.includes('.desktop.'));
|
|
64
|
+
const platformStyles = existingStyles.filter(style => style.includes(`.${platform}.`));
|
|
65
|
+
// Generar el entry client dinámicamente
|
|
66
|
+
const entryContent = `
|
|
67
|
+
import React from 'react'
|
|
68
|
+
import { createRoot } from 'react-dom/client'
|
|
69
|
+
import Page from '${page.abs}'
|
|
70
|
+
${generalStyles.map(style => `import '${style}'`).join('\n')}
|
|
71
|
+
${platformStyles.map(style => `import '${style}'`).join('\n')}
|
|
72
|
+
|
|
73
|
+
// Platform-specific styles
|
|
74
|
+
document.documentElement.classList.add('${platform}')
|
|
75
|
+
|
|
76
|
+
const container = document.getElementById('root')
|
|
77
|
+
if (container) {
|
|
78
|
+
const root = createRoot(container)
|
|
79
|
+
|
|
80
|
+
// Hydrate con props del servidor si están disponibles
|
|
81
|
+
const serverProps = (window as any).__SERVER_PROPS__ || {}
|
|
82
|
+
|
|
83
|
+
root.render(React.createElement(Page, serverProps))
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
return entryContent.trim();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Escribe entry files al filesystem
|
|
90
|
+
*/
|
|
91
|
+
async writeEntryFiles(entries) {
|
|
92
|
+
const fs = await import('fs/promises');
|
|
93
|
+
const path = await import('path');
|
|
94
|
+
await fs.mkdir(this.options.outputDir, { recursive: true });
|
|
95
|
+
for (const [filename, content] of Object.entries(entries)) {
|
|
96
|
+
const filepath = path.join(this.options.outputDir, `${filename}.tsx`);
|
|
97
|
+
await fs.writeFile(filepath, content, 'utf-8');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Limpia archivos temporales generados
|
|
102
|
+
*/
|
|
103
|
+
async cleanup() {
|
|
104
|
+
const fs = await import('fs/promises');
|
|
105
|
+
try {
|
|
106
|
+
await fs.rm(this.options.outputDir, { recursive: true, force: true });
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
// Ignorar errores si el directorio no existe
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=entry-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-generator.js","sourceRoot":"","sources":["../src/entry-generator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { createViteRouter, createAutoViteServer, detectPlatform, listDetectedPages, getPages } from './simple-router.js';
|
|
2
|
+
export type { ViteRouterOptions, AutoViteServerOptions } from './simple-router.js';
|
|
3
|
+
export { RouterFactory, createInitializedViteRouter } from './router-factory.js';
|
|
4
|
+
export { PageDetector } from './page-detector.js';
|
|
5
|
+
export { EntryGenerator } from './entry-generator.js';
|
|
6
|
+
export type { RouterFactoryOptions, RouteContext } from './router-factory.js';
|
|
7
|
+
export type { RouterOptions, PageRouterInfo } from './page-detector.js';
|
|
8
|
+
export type { EntryGeneratorOptions } from './entry-generator.js';
|
|
9
|
+
export type { PageInfo } from '@ressjs/core';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACT,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAGlF,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAC7E,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACvE,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAGjE,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Main API - Versión simplificada que funciona con el servidor existente
|
|
2
|
+
export { createViteRouter, createAutoViteServer, detectPlatform, listDetectedPages, getPages } from './simple-router.js';
|
|
3
|
+
// Legacy exports para compatibilidad (deprecated)
|
|
4
|
+
export { RouterFactory, createInitializedViteRouter } from './router-factory.js';
|
|
5
|
+
export { PageDetector } from './page-detector.js';
|
|
6
|
+
export { EntryGenerator } from './entry-generator.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACT,MAAM,oBAAoB,CAAA;AAI3B,kDAAkD;AAClD,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { PageInfo } from '@ressjs/core';
|
|
2
|
+
import { Request } from 'express';
|
|
3
|
+
export interface RouterOptions {
|
|
4
|
+
distPath?: string;
|
|
5
|
+
pagesDir?: string;
|
|
6
|
+
renderFunction?: (url: string) => Promise<{
|
|
7
|
+
html: string;
|
|
8
|
+
props: any;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export interface PageRouterInfo extends PageInfo {
|
|
12
|
+
entryPath?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class PageDetector {
|
|
15
|
+
private distPath;
|
|
16
|
+
private pagesDir;
|
|
17
|
+
constructor(options?: RouterOptions);
|
|
18
|
+
/**
|
|
19
|
+
* Detecta todas las páginas disponibles
|
|
20
|
+
*/
|
|
21
|
+
getDetectedPages(): PageRouterInfo[];
|
|
22
|
+
/**
|
|
23
|
+
* Genera entry-clients para todas las páginas
|
|
24
|
+
*/
|
|
25
|
+
generatePageEntries(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Obtiene input para Vite client build
|
|
28
|
+
*/
|
|
29
|
+
getClientBuildInput(): Promise<Record<string, string>>;
|
|
30
|
+
/**
|
|
31
|
+
* Detecta la plataforma desde el user agent
|
|
32
|
+
*/
|
|
33
|
+
detectPlatform(req: Request): string;
|
|
34
|
+
/**
|
|
35
|
+
* Encuentra una página por su ruta
|
|
36
|
+
*/
|
|
37
|
+
findPageByRoute(route: string): PageRouterInfo | undefined;
|
|
38
|
+
private getEntryPath;
|
|
39
|
+
/**
|
|
40
|
+
* Encuentra la página que coincide con una ruta específica
|
|
41
|
+
*/
|
|
42
|
+
matchRoute(requestPath: string, pages: PageInfo[]): PageInfo | null;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=page-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-detector.d.ts","sourceRoot":"","sources":["../src/page-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8C,QAAQ,EAAE,MAAM,cAAc,CAAA;AACnF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAIjC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC,CAAA;CACxE;AAED,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,QAAQ,CAAQ;gBAEZ,OAAO,GAAE,aAAkB;IAKvC;;OAEG;IACI,gBAAgB,IAAI,cAAc,EAAE;IAsB3C;;OAEG;IACU,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjD;;OAEG;IACU,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAInE;;OAEG;IACI,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM;IAO3C;;OAEG;IACI,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAQjE,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,GAAG,IAAI;CAuBpE"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { generateTempEntries, getClientEntriesInput } from '@ressjs/core';
|
|
2
|
+
import glob from 'fast-glob';
|
|
3
|
+
import { resolve } from 'path';
|
|
4
|
+
export class PageDetector {
|
|
5
|
+
constructor(options = {}) {
|
|
6
|
+
this.distPath = options.distPath || 'dist';
|
|
7
|
+
this.pagesDir = options.pagesDir || 'app/pages';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Detecta todas las páginas disponibles
|
|
11
|
+
*/
|
|
12
|
+
getDetectedPages() {
|
|
13
|
+
// Busca tanto page.tsx como page/index.tsx y prioriza el más corto
|
|
14
|
+
const files = glob.sync(`${this.pagesDir}/**/*.{tsx,jsx}`);
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
const pages = [];
|
|
17
|
+
for (const file of files) {
|
|
18
|
+
let route = file.replace(new RegExp(`^${this.pagesDir}`), '').replace(/\.tsx$|\.jsx$/, '');
|
|
19
|
+
route = route.replace(/\/index$/, '') || '/';
|
|
20
|
+
// Prioriza page.tsx sobre page/index.tsx
|
|
21
|
+
if (!seen.has(route)) {
|
|
22
|
+
seen.add(route);
|
|
23
|
+
pages.push({ route, file, abs: resolve(file) });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return pages.map(page => ({
|
|
27
|
+
...page,
|
|
28
|
+
entryPath: this.getEntryPath(page)
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Genera entry-clients para todas las páginas
|
|
33
|
+
*/
|
|
34
|
+
async generatePageEntries() {
|
|
35
|
+
await generateTempEntries(this.distPath);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Obtiene input para Vite client build
|
|
39
|
+
*/
|
|
40
|
+
async getClientBuildInput() {
|
|
41
|
+
return await getClientEntriesInput(this.distPath);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Detecta la plataforma desde el user agent
|
|
45
|
+
*/
|
|
46
|
+
detectPlatform(req) {
|
|
47
|
+
const ua = req.headers['user-agent'] || '';
|
|
48
|
+
if (/mobile|android|iphone|ipad|phone/i.test(ua))
|
|
49
|
+
return 'mobile';
|
|
50
|
+
if (/linux/i.test(ua))
|
|
51
|
+
return 'desktop.linux';
|
|
52
|
+
return 'desktop';
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Encuentra una página por su ruta
|
|
56
|
+
*/
|
|
57
|
+
findPageByRoute(route) {
|
|
58
|
+
const pages = this.getDetectedPages();
|
|
59
|
+
return pages.find(page => {
|
|
60
|
+
if (page.route === '/')
|
|
61
|
+
return route === '/' || route === '';
|
|
62
|
+
return route === page.route || route.startsWith(page.route + '/');
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
getEntryPath(page) {
|
|
66
|
+
const rel = page.file.replace(/^app\/pages\//, '').replace(/\.tsx$|\.jsx$/, '');
|
|
67
|
+
return `${this.distPath}/.entries/${rel}__entry-client.tsx`;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Encuentra la página que coincide con una ruta específica
|
|
71
|
+
*/
|
|
72
|
+
matchRoute(requestPath, pages) {
|
|
73
|
+
// Normalizar la ruta de request
|
|
74
|
+
const normalizedPath = requestPath === '/' ? '/' : requestPath.replace(/\/$/, '');
|
|
75
|
+
// Buscar coincidencia exacta primero
|
|
76
|
+
let match = pages.find(page => page.route === normalizedPath);
|
|
77
|
+
// Si no hay coincidencia exacta, buscar rutas dinámicas o wildcards
|
|
78
|
+
if (!match) {
|
|
79
|
+
// Para rutas como /page1, /page2, etc.
|
|
80
|
+
match = pages.find(page => {
|
|
81
|
+
// Convertir ruta de página a regex para matching
|
|
82
|
+
const routePattern = page.route
|
|
83
|
+
.replace(/\[([^\]]+)\]/g, '([^/]+)') // [param] -> captura
|
|
84
|
+
.replace(/\*/g, '.*'); // * -> wildcard
|
|
85
|
+
const regex = new RegExp(`^${routePattern}$`);
|
|
86
|
+
return regex.test(normalizedPath);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return match || null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=page-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-detector.js","sourceRoot":"","sources":["../src/page-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { PageInfo } from '@ressjs/core';
|
|
3
|
+
export interface RouterFactoryOptions {
|
|
4
|
+
pagesDir: string;
|
|
5
|
+
outputDir?: string;
|
|
6
|
+
enableSSR?: boolean;
|
|
7
|
+
enablePlatformDetection?: boolean;
|
|
8
|
+
staticDir?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface RouteContext {
|
|
11
|
+
page: PageInfo;
|
|
12
|
+
platform: 'desktop' | 'mobile';
|
|
13
|
+
entry: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class RouterFactory {
|
|
16
|
+
private options;
|
|
17
|
+
private pageDetector;
|
|
18
|
+
private entryGenerator;
|
|
19
|
+
private renderServer;
|
|
20
|
+
constructor(options: RouterFactoryOptions);
|
|
21
|
+
/**
|
|
22
|
+
* Crea un Express Router con todas las rutas automáticas
|
|
23
|
+
*/
|
|
24
|
+
createRouter(): Router;
|
|
25
|
+
/**
|
|
26
|
+
* Middleware para detectar páginas y preparar context
|
|
27
|
+
*/
|
|
28
|
+
private pageDetectionMiddleware;
|
|
29
|
+
/**
|
|
30
|
+
* Middleware para Server-Side Rendering
|
|
31
|
+
*/
|
|
32
|
+
private ssrMiddleware;
|
|
33
|
+
/**
|
|
34
|
+
* Middleware para archivos estáticos
|
|
35
|
+
*/
|
|
36
|
+
private staticMiddleware;
|
|
37
|
+
/**
|
|
38
|
+
* Inyecta el entry client específico del platform en el HTML
|
|
39
|
+
*/
|
|
40
|
+
private injectClientEntry;
|
|
41
|
+
/**
|
|
42
|
+
* Limpia archivos temporales
|
|
43
|
+
*/
|
|
44
|
+
cleanup(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Inicializa el router (genera entries iniciales)
|
|
47
|
+
*/
|
|
48
|
+
initialize(): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Factory function para crear un router fácilmente
|
|
52
|
+
*/
|
|
53
|
+
export declare function createViteRouter(options: RouterFactoryOptions): Router;
|
|
54
|
+
/**
|
|
55
|
+
* Factory function async para inicializar y crear el router
|
|
56
|
+
*/
|
|
57
|
+
export declare function createInitializedViteRouter(options: RouterFactoryOptions): Promise<Router>;
|
|
58
|
+
//# sourceMappingURL=router-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-factory.d.ts","sourceRoot":"","sources":["../src/router-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAmC,MAAM,SAAS,CAAA;AAGjE,OAAO,EAAsB,QAAQ,EAAE,MAAM,cAAc,CAAA;AAE3D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,QAAQ,CAAA;IACd,QAAQ,EAAE,SAAS,GAAG,QAAQ,CAAA;IAC9B,KAAK,EAAE,MAAM,CAAA;CACd;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,YAAY,CAAK;gBAEb,OAAO,EAAE,oBAAoB;IAwBzC;;OAEG;IACH,YAAY,IAAI,MAAM;IAiBtB;;OAEG;YACW,uBAAuB;IAiDrC;;OAEG;YACW,aAAa;IA4B3B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAUxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAqBzB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAGlC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAGtE;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAIhG"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { PageDetector } from './page-detector.js';
|
|
3
|
+
import { EntryGenerator } from './entry-generator.js';
|
|
4
|
+
import { createRenderServer } from '@ressjs/core';
|
|
5
|
+
export class RouterFactory {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.options = {
|
|
8
|
+
outputDir: 'temp',
|
|
9
|
+
enableSSR: true,
|
|
10
|
+
enablePlatformDetection: true,
|
|
11
|
+
staticDir: 'public',
|
|
12
|
+
...options
|
|
13
|
+
};
|
|
14
|
+
this.pageDetector = new PageDetector({
|
|
15
|
+
pagesDir: this.options.pagesDir,
|
|
16
|
+
distPath: this.options.outputDir
|
|
17
|
+
});
|
|
18
|
+
this.entryGenerator = new EntryGenerator({
|
|
19
|
+
pagesDir: this.options.pagesDir,
|
|
20
|
+
outputDir: this.options.outputDir
|
|
21
|
+
});
|
|
22
|
+
if (this.options.enableSSR) {
|
|
23
|
+
this.renderServer = createRenderServer();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Crea un Express Router con todas las rutas automáticas
|
|
28
|
+
*/
|
|
29
|
+
createRouter() {
|
|
30
|
+
const router = Router();
|
|
31
|
+
// Middleware para detectar páginas y generar entries
|
|
32
|
+
router.use(this.pageDetectionMiddleware.bind(this));
|
|
33
|
+
// Middleware para SSR
|
|
34
|
+
if (this.options.enableSSR) {
|
|
35
|
+
router.use(this.ssrMiddleware.bind(this));
|
|
36
|
+
}
|
|
37
|
+
// Fallback para servir archivos estáticos
|
|
38
|
+
router.use(this.staticMiddleware.bind(this));
|
|
39
|
+
return router;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Middleware para detectar páginas y preparar context
|
|
43
|
+
*/
|
|
44
|
+
async pageDetectionMiddleware(req, _res, next) {
|
|
45
|
+
try {
|
|
46
|
+
console.log(`[ViteRouter] Processing request: ${req.path}`);
|
|
47
|
+
const detectedPages = await this.pageDetector.getDetectedPages();
|
|
48
|
+
console.log(`[ViteRouter] Detected ${detectedPages.length} pages:`, detectedPages.map(p => p.route));
|
|
49
|
+
const matchedPage = this.pageDetector.matchRoute(req.path, detectedPages);
|
|
50
|
+
console.log(`[ViteRouter] Matched page for ${req.path}:`, matchedPage);
|
|
51
|
+
if (!matchedPage) {
|
|
52
|
+
console.log(`[ViteRouter] No page matched for ${req.path}, passing to next middleware`);
|
|
53
|
+
return next();
|
|
54
|
+
}
|
|
55
|
+
// Detectar platform si está habilitado
|
|
56
|
+
const platform = this.options.enablePlatformDetection
|
|
57
|
+
? this.entryGenerator.detectPlatformFromRequest(req)
|
|
58
|
+
: 'desktop';
|
|
59
|
+
console.log(`[ViteRouter] Detected platform: ${platform}`);
|
|
60
|
+
// Generar entry específico para este platform
|
|
61
|
+
const entry = await this.entryGenerator.generatePlatformSpecificEntry(matchedPage.route, platform, detectedPages);
|
|
62
|
+
console.log(`[ViteRouter] Generated entry for ${matchedPage.route}`);
|
|
63
|
+
req.routeContext = {
|
|
64
|
+
page: matchedPage,
|
|
65
|
+
platform,
|
|
66
|
+
entry
|
|
67
|
+
};
|
|
68
|
+
next();
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
console.error('Error in page detection middleware:', error);
|
|
72
|
+
next(error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Middleware para Server-Side Rendering
|
|
77
|
+
*/
|
|
78
|
+
async ssrMiddleware(req, res, next) {
|
|
79
|
+
const context = req.routeContext;
|
|
80
|
+
if (!context) {
|
|
81
|
+
return next();
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
console.log(`[ViteRouter] SSR rendering for ${req.url}`);
|
|
85
|
+
// Usar el renderServer del core con la URL
|
|
86
|
+
const html = await this.renderServer({ url: req.url });
|
|
87
|
+
// Inyectar el entry client específico del platform
|
|
88
|
+
const finalHtml = this.injectClientEntry(html, context);
|
|
89
|
+
res.setHeader('Content-Type', 'text/html');
|
|
90
|
+
res.send(finalHtml);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error('SSR Error:', error);
|
|
94
|
+
next(error);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Middleware para archivos estáticos
|
|
99
|
+
*/
|
|
100
|
+
staticMiddleware(_req, _res, next) {
|
|
101
|
+
// Si llegamos aquí, no se encontró una página
|
|
102
|
+
// Express.static se encargará de servir archivos estáticos
|
|
103
|
+
next();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Inyecta el entry client específico del platform en el HTML
|
|
107
|
+
*/
|
|
108
|
+
injectClientEntry(html, context) {
|
|
109
|
+
// Buscar el punto de inserción del script
|
|
110
|
+
const scriptInsertPoint = html.indexOf('</head>');
|
|
111
|
+
if (scriptInsertPoint === -1) {
|
|
112
|
+
return html;
|
|
113
|
+
}
|
|
114
|
+
// Generar script tag con el entry específico
|
|
115
|
+
const scriptTag = `
|
|
116
|
+
<script>
|
|
117
|
+
// Platform detection
|
|
118
|
+
document.documentElement.classList.add('${context.platform}')
|
|
119
|
+
|
|
120
|
+
// Entry específico del platform
|
|
121
|
+
${context.entry}
|
|
122
|
+
</script>`;
|
|
123
|
+
return html.slice(0, scriptInsertPoint) + scriptTag + html.slice(scriptInsertPoint);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Limpia archivos temporales
|
|
127
|
+
*/
|
|
128
|
+
async cleanup() {
|
|
129
|
+
await this.entryGenerator.cleanup();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Inicializa el router (genera entries iniciales)
|
|
133
|
+
*/
|
|
134
|
+
async initialize() {
|
|
135
|
+
await this.entryGenerator.generateDynamicEntries();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Factory function para crear un router fácilmente
|
|
140
|
+
*/
|
|
141
|
+
export function createViteRouter(options) {
|
|
142
|
+
const factory = new RouterFactory(options);
|
|
143
|
+
return factory.createRouter();
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Factory function async para inicializar y crear el router
|
|
147
|
+
*/
|
|
148
|
+
export async function createInitializedViteRouter(options) {
|
|
149
|
+
const factory = new RouterFactory(options);
|
|
150
|
+
await factory.initialize();
|
|
151
|
+
return factory.createRouter();
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=router-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-factory.js","sourceRoot":"","sources":["../src/router-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAmC,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAY,MAAM,cAAc,CAAA;AAgB3D,MAAM,OAAO,aAAa;IAMxB,YAAY,OAA6B;QACvC,IAAI,CAAC,OAAO,GAAG;YACb,SAAS,EAAE,MAAM;YACjB,SAAS,EAAE,IAAI;YACf,uBAAuB,EAAE,IAAI;YAC7B,SAAS,EAAE,QAAQ;YACnB,GAAG,OAAO;SACX,CAAA;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC;YACnC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;YAC/B,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;SACjC,CAAC,CAAA;QAEF,IAAI,CAAC,cAAc,GAAG,IAAI,cAAc,CAAC;YACvC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ;YAC/B,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;SAClC,CAAC,CAAA;QAEF,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,GAAG,kBAAkB,EAAE,CAAA;QAC1C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,YAAY;QACV,MAAM,MAAM,GAAG,MAAM,EAAE,CAAA;QAEvB,qDAAqD;QACrD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAEnD,sBAAsB;QACtB,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC3C,CAAC;QAED,0CAA0C;QAC1C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAE5C,OAAO,MAAM,CAAA;IACf,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,uBAAuB,CACnC,GAAY,EACZ,IAAc,EACd,IAAkB;QAElB,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,oCAAoC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAA;YAE3D,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,CAAA;YAChE,OAAO,CAAC,GAAG,CAAC,yBAAyB,aAAa,CAAC,MAAM,SAAS,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;YAEpG,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;YACzE,OAAO,CAAC,GAAG,CAAC,iCAAiC,GAAG,CAAC,IAAI,GAAG,EAAE,WAAW,CAAC,CAAA;YAEtE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,oCAAoC,GAAG,CAAC,IAAI,8BAA8B,CAAC,CAAA;gBACvF,OAAO,IAAI,EAAE,CAAA;YACf,CAAC;YAED,uCAAuC;YACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,uBAAuB;gBACnD,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,yBAAyB,CAAC,GAAG,CAAC;gBACpD,CAAC,CAAC,SAAS,CAAA;YAEb,OAAO,CAAC,GAAG,CAAC,mCAAmC,QAAQ,EAAE,CAAC,CAAA;YAE1D,8CAA8C;YAC9C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,6BAA6B,CACnE,WAAW,CAAC,KAAK,EACjB,QAAQ,EACR,aAAa,CACd,CAAA;YAED,OAAO,CAAC,GAAG,CAAC,oCAAoC,WAAW,CAAC,KAAK,EAAE,CAAC,CAGnE;YAAC,GAAW,CAAC,YAAY,GAAG;gBAC3B,IAAI,EAAE,WAAW;gBACjB,QAAQ;gBACR,KAAK;aACU,CAAA;YAEjB,IAAI,EAAE,CAAA;QACR,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAA;YAC3D,IAAI,CAAC,KAAK,CAAC,CAAA;QACb,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa,CACzB,GAAY,EACZ,GAAa,EACb,IAAkB;QAElB,MAAM,OAAO,GAAI,GAAW,CAAC,YAA4B,CAAA;QAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,EAAE,CAAA;QACf,CAAC;QAED,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,kCAAkC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAA;YAExD,2CAA2C;YAC3C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAA;YAEtD,mDAAmD;YACnD,MAAM,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YAEvD,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;YAC1C,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;YAClC,IAAI,CAAC,KAAK,CAAC,CAAA;QACb,CAAC;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB,CACtB,IAAa,EACb,IAAc,EACd,IAAkB;QAElB,8CAA8C;QAC9C,2DAA2D;QAC3D,IAAI,EAAE,CAAA;IACR,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,IAAY,EAAE,OAAqB;QAC3D,0CAA0C;QAC1C,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAEjD,IAAI,iBAAiB,KAAK,CAAC,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAA;QACb,CAAC;QAED,6CAA6C;QAC7C,MAAM,SAAS,GAAG;;;8CAGwB,OAAO,CAAC,QAAQ;;;MAGxD,OAAO,CAAC,KAAK;YACP,CAAA;QAER,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACrF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAA;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,CAAA;IACpD,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA6B;IAC5D,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAA;IAC1C,OAAO,OAAO,CAAC,YAAY,EAAE,CAAA;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,OAA6B;IAC7E,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAA;IAC1C,MAAM,OAAO,CAAC,UAAU,EAAE,CAAA;IAC1B,OAAO,OAAO,CAAC,YAAY,EAAE,CAAA;AAC/B,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
export interface ViteRouterOptions {
|
|
3
|
+
enablePlatformDetection?: boolean;
|
|
4
|
+
vite?: any;
|
|
5
|
+
manifest?: any;
|
|
6
|
+
templateHtml?: string;
|
|
7
|
+
isProduction?: boolean;
|
|
8
|
+
renderFunction?: (options: {
|
|
9
|
+
url: string;
|
|
10
|
+
platform: string;
|
|
11
|
+
req: any;
|
|
12
|
+
}) => Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
export interface AutoViteServerOptions {
|
|
15
|
+
port?: number;
|
|
16
|
+
base?: string;
|
|
17
|
+
enablePlatformDetection?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Crea un servidor Express completo con vite-router automático
|
|
21
|
+
* Esta es la función de alto nivel para casos simples
|
|
22
|
+
*/
|
|
23
|
+
export declare function createAutoViteServer(options?: AutoViteServerOptions): Promise<{
|
|
24
|
+
app: import("express-serve-static-core").Express;
|
|
25
|
+
vite: any;
|
|
26
|
+
start: () => import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Crea un Express router que automáticamente detecta páginas, las rutea,
|
|
30
|
+
* y maneja todo el SSR + hidratación del cliente.
|
|
31
|
+
*
|
|
32
|
+
* Si no se pasan opciones, auto-configura Vite, manifest, templates, etc.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createViteRouter(options?: ViteRouterOptions): Router;
|
|
35
|
+
/**
|
|
36
|
+
* Detecta platform desde el User-Agent
|
|
37
|
+
*/
|
|
38
|
+
export declare function detectPlatform(userAgent: string): 'desktop' | 'mobile';
|
|
39
|
+
/**
|
|
40
|
+
* Helper para listar páginas detectadas
|
|
41
|
+
*/
|
|
42
|
+
export declare function listDetectedPages(): import("@ressjs/core").PageInfo[];
|
|
43
|
+
export { getPages } from '@ressjs/core';
|
|
44
|
+
//# sourceMappingURL=simple-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-router.d.ts","sourceRoot":"","sources":["../src/simple-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAKhC,MAAM,WAAW,iBAAiB;IAChC,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,IAAI,CAAC,EAAE,GAAG,CAAA;IACV,QAAQ,CAAC,EAAE,GAAG,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,GAAG,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAC3F;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAClC;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B;;;;GA6E7E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAWxE;AAgTD;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAItE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,sCAEhC;AAGD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { getPages, createRenderServer, generateTempEntries } from '@ressjs/core';
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
4
|
+
import express from 'express';
|
|
5
|
+
/**
|
|
6
|
+
* Crea un servidor Express completo con vite-router automático
|
|
7
|
+
* Esta es la función de alto nivel para casos simples
|
|
8
|
+
*/
|
|
9
|
+
export async function createAutoViteServer(options = {}) {
|
|
10
|
+
const { port = 5173, base = '/', enablePlatformDetection = true } = options;
|
|
11
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
12
|
+
const app = express();
|
|
13
|
+
let vite;
|
|
14
|
+
let manifest = {};
|
|
15
|
+
let templateHtml = '';
|
|
16
|
+
// Configuración automática de Vite
|
|
17
|
+
if (!isProduction) {
|
|
18
|
+
console.log('[AutoViteServer] Setting up development server...');
|
|
19
|
+
const { createServer } = await import('vite');
|
|
20
|
+
vite = await createServer({
|
|
21
|
+
server: { middlewareMode: true },
|
|
22
|
+
appType: 'custom',
|
|
23
|
+
base,
|
|
24
|
+
});
|
|
25
|
+
app.use(vite.middlewares);
|
|
26
|
+
// Sirve los entry-client generados en dev (incluyendo los específicos por plataforma)
|
|
27
|
+
app.use('/dist/.entries', express.static('dist/.entries'));
|
|
28
|
+
// Cargar manifest si existe
|
|
29
|
+
try {
|
|
30
|
+
manifest = JSON.parse(await fs.readFile('./dist/server/.vite/manifest.json', 'utf-8'));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
console.log('[AutoViteServer] No server manifest found (normal in dev)');
|
|
34
|
+
manifest = {};
|
|
35
|
+
}
|
|
36
|
+
// Generar entries automáticamente
|
|
37
|
+
await generateTempEntries();
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
console.log('[AutoViteServer] Setting up production server...');
|
|
41
|
+
const compression = (await import('compression')).default;
|
|
42
|
+
const sirv = (await import('sirv')).default;
|
|
43
|
+
app.use(compression());
|
|
44
|
+
app.use(base, sirv('./dist/client', { extensions: [] }));
|
|
45
|
+
// Cargar assets de producción
|
|
46
|
+
manifest = JSON.parse(await fs.readFile('./dist/client/.vite/manifest.json', 'utf-8'));
|
|
47
|
+
templateHtml = await fs.readFile('./index.html', 'utf-8');
|
|
48
|
+
}
|
|
49
|
+
// Crear vite-router con configuración automática
|
|
50
|
+
const viteRouter = createViteRouter({
|
|
51
|
+
enablePlatformDetection,
|
|
52
|
+
vite,
|
|
53
|
+
manifest,
|
|
54
|
+
templateHtml,
|
|
55
|
+
isProduction
|
|
56
|
+
});
|
|
57
|
+
app.use('/', viteRouter);
|
|
58
|
+
app.use(express.static('public'));
|
|
59
|
+
// Función para iniciar el servidor
|
|
60
|
+
const start = () => {
|
|
61
|
+
return app.listen(port, () => {
|
|
62
|
+
const pages = getPages();
|
|
63
|
+
console.log(`🚀 Auto Vite Server started at http://localhost:${port}`);
|
|
64
|
+
console.log(`📄 Auto-detected routes:`);
|
|
65
|
+
pages.forEach(page => {
|
|
66
|
+
console.log(` ${page.route} -> ${page.file}`);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
return { app, vite, start };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Crea un Express router que automáticamente detecta páginas, las rutea,
|
|
74
|
+
* y maneja todo el SSR + hidratación del cliente.
|
|
75
|
+
*
|
|
76
|
+
* Si no se pasan opciones, auto-configura Vite, manifest, templates, etc.
|
|
77
|
+
*/
|
|
78
|
+
export function createViteRouter(options = {}) {
|
|
79
|
+
// Si no se pasan opciones críticas, configurar automáticamente
|
|
80
|
+
const needsAutoConfig = !options.vite && !options.manifest && !options.templateHtml;
|
|
81
|
+
if (needsAutoConfig) {
|
|
82
|
+
console.log('[ViteRouter] Auto-configuring...');
|
|
83
|
+
return createAutoConfiguredRouter(options);
|
|
84
|
+
}
|
|
85
|
+
// Configuración manual (para casos avanzados)
|
|
86
|
+
return createManualRouter(options);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Router con configuración automática
|
|
90
|
+
*/
|
|
91
|
+
function createAutoConfiguredRouter(options) {
|
|
92
|
+
const { enablePlatformDetection = true, renderFunction } = options;
|
|
93
|
+
const isProduction = process.env.NODE_ENV === 'production';
|
|
94
|
+
let vite;
|
|
95
|
+
let manifest = {};
|
|
96
|
+
let templateHtml = '';
|
|
97
|
+
let renderServer = null;
|
|
98
|
+
let initialized = false;
|
|
99
|
+
// Router principal que va a manejar todo
|
|
100
|
+
const mainRouter = Router();
|
|
101
|
+
// Función para inicializar una sola vez
|
|
102
|
+
const initializeIfNeeded = async () => {
|
|
103
|
+
if (initialized)
|
|
104
|
+
return { vite, manifest, templateHtml };
|
|
105
|
+
if (!isProduction) {
|
|
106
|
+
console.log('[ViteRouter] Setting up development mode...');
|
|
107
|
+
const { createServer } = await import('vite');
|
|
108
|
+
vite = await createServer({
|
|
109
|
+
server: { middlewareMode: true },
|
|
110
|
+
appType: 'custom',
|
|
111
|
+
base: process.env.BASE || '/',
|
|
112
|
+
});
|
|
113
|
+
// Agregar Vite middleware al router principal
|
|
114
|
+
mainRouter.use(vite.middlewares);
|
|
115
|
+
// Cargar manifest si existe
|
|
116
|
+
try {
|
|
117
|
+
manifest = JSON.parse(await fs.readFile('./dist/server/.vite/manifest.json', 'utf-8'));
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
console.log('[ViteRouter] No server manifest found (normal in dev)');
|
|
121
|
+
manifest = {};
|
|
122
|
+
}
|
|
123
|
+
// Generar entries automáticamente
|
|
124
|
+
await generateTempEntries();
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
console.log('[ViteRouter] Setting up production mode...');
|
|
128
|
+
// Configurar middleware de producción
|
|
129
|
+
const compression = (await import('compression')).default;
|
|
130
|
+
const sirv = (await import('sirv')).default;
|
|
131
|
+
mainRouter.use(compression());
|
|
132
|
+
mainRouter.use(sirv('./dist/client', { extensions: [] }));
|
|
133
|
+
// Cargar assets de producción
|
|
134
|
+
manifest = JSON.parse(await fs.readFile('./dist/client/.vite/manifest.json', 'utf-8'));
|
|
135
|
+
templateHtml = await fs.readFile('./index.html', 'utf-8');
|
|
136
|
+
}
|
|
137
|
+
initialized = true;
|
|
138
|
+
return { vite, manifest, templateHtml };
|
|
139
|
+
};
|
|
140
|
+
// Crear las rutas de páginas
|
|
141
|
+
const pages = getPages();
|
|
142
|
+
console.log(`[ViteRouter] Creating auto-configured router for ${pages.length} pages`);
|
|
143
|
+
pages.forEach(page => {
|
|
144
|
+
console.log(`[ViteRouter] Route: ${page.route} -> ${page.file}`);
|
|
145
|
+
mainRouter.get(page.route, async (req, res, next) => {
|
|
146
|
+
try {
|
|
147
|
+
// Inicializar si es necesario (lazy initialization)
|
|
148
|
+
await initializeIfNeeded();
|
|
149
|
+
// Detectar platform
|
|
150
|
+
let platform = 'desktop';
|
|
151
|
+
if (enablePlatformDetection) {
|
|
152
|
+
const userAgent = req.headers['user-agent']?.toLowerCase() || '';
|
|
153
|
+
const isMobile = ['mobile', 'android', 'iphone', 'ipad', 'blackberry', 'windows phone']
|
|
154
|
+
.some(keyword => userAgent.includes(keyword));
|
|
155
|
+
platform = isMobile ? 'mobile' : 'desktop';
|
|
156
|
+
}
|
|
157
|
+
// Si hay función de render personalizada, usarla
|
|
158
|
+
if (renderFunction) {
|
|
159
|
+
const html = await renderFunction({ url: req.url, platform, req });
|
|
160
|
+
res.setHeader('Content-Type', 'text/html');
|
|
161
|
+
res.send(html);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
// Crear renderServer lazy-loading
|
|
165
|
+
if (!renderServer) {
|
|
166
|
+
const renderOptions = vite ? { vite } : {};
|
|
167
|
+
renderServer = createRenderServer(renderOptions);
|
|
168
|
+
}
|
|
169
|
+
// Renderizar
|
|
170
|
+
const urlObj = new URL(req.url, 'http://localhost');
|
|
171
|
+
const pathname = urlObj.pathname;
|
|
172
|
+
const rendered = await renderServer({ url: pathname });
|
|
173
|
+
// Obtener template
|
|
174
|
+
let template;
|
|
175
|
+
if (!isProduction) {
|
|
176
|
+
template = await fs.readFile('./index.html', 'utf-8');
|
|
177
|
+
template = await vite.transformIndexHtml(req.url, template);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
template = templateHtml;
|
|
181
|
+
}
|
|
182
|
+
// Generar HTML completo
|
|
183
|
+
const html = generateFullHTML(template, rendered, page, manifest, platform, isProduction);
|
|
184
|
+
res.setHeader('Content-Type', 'text/html');
|
|
185
|
+
res.send(html);
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
console.error(`[ViteRouter] Error handling ${req.url}:`, error);
|
|
189
|
+
if (vite?.ssrFixStacktrace) {
|
|
190
|
+
vite.ssrFixStacktrace(error);
|
|
191
|
+
}
|
|
192
|
+
next(error);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
return mainRouter;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Router con configuración manual (para casos avanzados)
|
|
200
|
+
*/
|
|
201
|
+
function createManualRouter(options) {
|
|
202
|
+
const { enablePlatformDetection = true, vite, manifest = {}, templateHtml = '', isProduction = process.env.NODE_ENV === 'production', renderFunction } = options;
|
|
203
|
+
const router = Router();
|
|
204
|
+
const pages = getPages();
|
|
205
|
+
let renderServer = null;
|
|
206
|
+
console.log(`[ViteRouter] Creating router for ${pages.length} pages`);
|
|
207
|
+
pages.forEach(page => {
|
|
208
|
+
console.log(`[ViteRouter] Route: ${page.route} -> ${page.file}`);
|
|
209
|
+
router.get(page.route, async (req, res, next) => {
|
|
210
|
+
try {
|
|
211
|
+
// Detectar platform
|
|
212
|
+
let platform = 'desktop';
|
|
213
|
+
if (enablePlatformDetection) {
|
|
214
|
+
const userAgent = req.headers['user-agent']?.toLowerCase() || '';
|
|
215
|
+
const isMobile = ['mobile', 'android', 'iphone', 'ipad', 'blackberry', 'windows phone']
|
|
216
|
+
.some(keyword => userAgent.includes(keyword));
|
|
217
|
+
platform = isMobile ? 'mobile' : 'desktop';
|
|
218
|
+
}
|
|
219
|
+
// Si hay función de render personalizada, usarla
|
|
220
|
+
if (renderFunction) {
|
|
221
|
+
const html = await renderFunction({ url: req.url, platform, req });
|
|
222
|
+
res.setHeader('Content-Type', 'text/html');
|
|
223
|
+
res.send(html);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
// Crear renderServer lazy-loading
|
|
227
|
+
if (!renderServer) {
|
|
228
|
+
const renderOptions = vite ? { vite } : {};
|
|
229
|
+
renderServer = createRenderServer(renderOptions);
|
|
230
|
+
}
|
|
231
|
+
// Renderizar
|
|
232
|
+
const urlObj = new URL(req.url, 'http://localhost');
|
|
233
|
+
const pathname = urlObj.pathname;
|
|
234
|
+
const rendered = await renderServer({ url: pathname });
|
|
235
|
+
// Obtener template
|
|
236
|
+
let template;
|
|
237
|
+
if (!isProduction) {
|
|
238
|
+
template = await fs.readFile('./index.html', 'utf-8');
|
|
239
|
+
template = await vite.transformIndexHtml(req.url, template);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
template = templateHtml;
|
|
243
|
+
}
|
|
244
|
+
// Generar HTML completo
|
|
245
|
+
const html = generateFullHTML(template, rendered, page, manifest, platform, isProduction);
|
|
246
|
+
res.setHeader('Content-Type', 'text/html');
|
|
247
|
+
res.send(html);
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
console.error(`[ViteRouter] Error handling ${req.url}:`, error);
|
|
251
|
+
if (vite?.ssrFixStacktrace) {
|
|
252
|
+
vite.ssrFixStacktrace(error);
|
|
253
|
+
}
|
|
254
|
+
next(error);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
return router;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Genera el HTML completo con assets y hidratación
|
|
262
|
+
*/
|
|
263
|
+
function generateFullHTML(template, rendered, page, manifest, platform, isProduction) {
|
|
264
|
+
// Función para obtener script del cliente según la plataforma
|
|
265
|
+
function getClientScript(pageFile, platform) {
|
|
266
|
+
const rel = pageFile.replace(/^app\/pages\//, '').replace(/\.tsx$|\.jsx$/, '');
|
|
267
|
+
if (!isProduction) {
|
|
268
|
+
// En dev, intentar cargar el entry-client específico de la plataforma
|
|
269
|
+
if (platform === 'mobile') {
|
|
270
|
+
return `/dist/.entries/${rel}__entry-client.mobile.tsx`;
|
|
271
|
+
}
|
|
272
|
+
return `/dist/.entries/${rel}__entry-client.tsx`;
|
|
273
|
+
}
|
|
274
|
+
// En producción, buscar en el manifest el entry-client correcto
|
|
275
|
+
let entryKey = `dist/.entries/${rel}__entry-client.tsx`;
|
|
276
|
+
if (platform === 'mobile') {
|
|
277
|
+
const mobileKey = `dist/.entries/${rel}__entry-client.mobile.tsx`;
|
|
278
|
+
if (manifest[mobileKey]) {
|
|
279
|
+
entryKey = mobileKey;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
const chunk = manifest[entryKey];
|
|
283
|
+
return chunk ? `/${chunk.file}` : null;
|
|
284
|
+
}
|
|
285
|
+
// Función para obtener CSS del cliente (restaurado para producción)
|
|
286
|
+
function getClientCss(pageFile, platform) {
|
|
287
|
+
if (!isProduction || !pageFile) {
|
|
288
|
+
return ''; // En dev, Vite maneja los estilos automáticamente vía HMR
|
|
289
|
+
}
|
|
290
|
+
// En producción, el CSS se incluye en el entry-client correspondiente
|
|
291
|
+
const rel = pageFile.replace(/^app\/pages\//, '').replace(/\.tsx$|\.jsx$/, '');
|
|
292
|
+
// Determinar qué entry-client usar según la plataforma
|
|
293
|
+
let entryKey = `dist/.entries/${rel}__entry-client.tsx`;
|
|
294
|
+
if (platform === 'mobile') {
|
|
295
|
+
const mobileKey = `dist/.entries/${rel}__entry-client.mobile.tsx`;
|
|
296
|
+
if (manifest[mobileKey]) {
|
|
297
|
+
entryKey = mobileKey;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
const entryChunk = manifest[entryKey];
|
|
301
|
+
if (entryChunk && entryChunk.css) {
|
|
302
|
+
return entryChunk.css.map((cssFile) => `<link rel="stylesheet" href="/${cssFile}">`).join('');
|
|
303
|
+
}
|
|
304
|
+
return '';
|
|
305
|
+
}
|
|
306
|
+
// Generar HTML completo
|
|
307
|
+
const scriptSrc = getClientScript(page.file, platform);
|
|
308
|
+
const scriptTag = scriptSrc ? `<script type="module" src="${scriptSrc}"></script>` : '';
|
|
309
|
+
const cssLinks = page?.file ? getClientCss(page.file, platform) : '';
|
|
310
|
+
const html = template
|
|
311
|
+
.replace('<!--app-head-->', cssLinks)
|
|
312
|
+
.replace('<!--app-html-->', rendered.html)
|
|
313
|
+
.replace('</body>', `<script>
|
|
314
|
+
window.__INITIAL_PROPS__=${JSON.stringify(rendered.props || {})};
|
|
315
|
+
window.__PAGE_ROUTE__=${JSON.stringify(page.route)};
|
|
316
|
+
window.__PAGE_FILE__=${JSON.stringify(page.file)};
|
|
317
|
+
</script>
|
|
318
|
+
${scriptTag}
|
|
319
|
+
</body>`);
|
|
320
|
+
// Inyectar platform class si no es desktop
|
|
321
|
+
return platform !== 'desktop'
|
|
322
|
+
? html.replace('<html', `<html class="${platform}"`)
|
|
323
|
+
: html;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Detecta platform desde el User-Agent
|
|
327
|
+
*/
|
|
328
|
+
export function detectPlatform(userAgent) {
|
|
329
|
+
const ua = userAgent.toLowerCase();
|
|
330
|
+
const mobileKeywords = ['mobile', 'android', 'iphone', 'ipad', 'blackberry', 'windows phone'];
|
|
331
|
+
return mobileKeywords.some(keyword => ua.includes(keyword)) ? 'mobile' : 'desktop';
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Helper para listar páginas detectadas
|
|
335
|
+
*/
|
|
336
|
+
export function listDetectedPages() {
|
|
337
|
+
return getPages();
|
|
338
|
+
}
|
|
339
|
+
// Re-export del core para conveniencia
|
|
340
|
+
export { getPages } from '@ressjs/core';
|
|
341
|
+
//# sourceMappingURL=simple-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-router.js","sourceRoot":"","sources":["../src/simple-router.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ressjs/vite-router",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Express router factory for ress.js with automatic page detection and SSR",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"dev": "tsc --watch",
|
|
23
|
+
"clean": "rm -rf dist",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"ssr",
|
|
28
|
+
"react",
|
|
29
|
+
"vite",
|
|
30
|
+
"express",
|
|
31
|
+
"router"
|
|
32
|
+
],
|
|
33
|
+
"author": "ressjs team",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/compression": "^1.7.5",
|
|
37
|
+
"@types/express": "^5.0.0",
|
|
38
|
+
"@types/node": "^22.13.4",
|
|
39
|
+
"typescript": "~5.7.3"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@ressjs/core": "^0.1.0",
|
|
43
|
+
"chokidar": "^4.0.3",
|
|
44
|
+
"compression": "^1.8.0",
|
|
45
|
+
"express": "^5.0.1",
|
|
46
|
+
"sirv": "^3.0.1"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"vite": "^6.0.0"
|
|
50
|
+
},
|
|
51
|
+
"gitHead": "192e13e79f9a9ec584b4e1c51c2aa04bd81161ec"
|
|
52
|
+
}
|