Guía de Migración
Esta guía te ayudará a migrar desde diferentes frameworks y versiones hacia Fox Framework, minimizando el esfuerzo y asegurando una transición suave.
v1.4.2 → v1.4.3 — CLI como paquete separado
Breaking changes
tsfox binary se mueve a @foxframework/cli
El binario tsfox ya no está incluido en @foxframework/core. Instala el paquete dedicado:
# Antes (v1.4.2 y anteriores) — tsfox venía incluido con core
npm install @foxframework/core
# Ahora (v1.4.3+) — instalación explícita
npm install @foxframework/core
npm install -g @foxframework/cli # instalación global (recomendado)
# o como devDependency del proyecto
npm install --save-dev @foxframework/cliexpress y axios son ahora peerDependencies de @foxframework/core
Si tu proyecto los usa (directamente o via @foxframework/core), asegúrate de tenerlos en tus dependencias:
npm install express axioscommander, inquirer, ora eliminados de @foxframework/core
Si importabas estas librerías transitivamente desde @foxframework/core, instálalas directamente:
npm install commander inquirer ora🔄 Migración desde Express.js
Evaluación Pre-Migración
Antes de comenzar, evalúa tu proyecto actual:
# Analiza tu proyecto Express existente
npx @foxframework/analyzer analyze ./src
# Genera reporte de migración
npx @foxframework/analyzer migration-reportPaso 1: Preparación del Entorno
# Instalar Fox Framework en proyecto existente
npm install @foxframework/core @foxframework/migration-tools
# Backup del proyecto
git checkout -b migration-to-fox-frameworkPaso 2: Migración Gradual del Servidor
Antes (Express):
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const app = express();
app.use(cors());
app.use(helmet());
app.use(express.json());
// Rutas
app.get('/api/users', (req, res) => {
// lógica
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});Después (Fox Framework):
import { FoxFactory } from '@foxframework/core';
import { corsMiddleware, helmetMiddleware } from '@foxframework/core';
const server = FoxFactory.createServer({
port: 3000,
middleware: [
corsMiddleware(),
helmetMiddleware()
]
});
// Mantener rutas Express temporalmente
server.express.get('/api/users', (req, res) => {
// misma lógica
});
server.listen();Paso 3: Migrar Rutas a Controllers
Crear estructura de Fox Framework:
# Generar controllers desde rutas Express
npx fox generate:from-express ./routes
# Estructura generada:
src/
├── controllers/
│ ├── user.controller.ts
│ └── auth.controller.ts
├── services/
│ └── user.service.ts
└── routes/
└── index.tsRuta Express original:
app.get('/api/users/:id', async (req, res) => {
try {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json({ success: true, data: user });
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
});Controller Fox Framework:
import { FoxController, Request, Response } from '@foxframework/core';
import { UserService } from '../services/user.service';
export class UserController extends FoxController {
constructor(private userService: UserService) {
super();
}
async getUser(req: Request, res: Response): Promise<void> {
try {
const user = await this.userService.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json({ success: true, data: user });
} catch (error) {
this.handleError(error, res);
}
}
}Paso 4: Migrar Middleware Personalizado
Express Middleware:
const authMiddleware = (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
if (err) {
return res.status(401).json({ error: 'Invalid token' });
}
req.user = decoded;
next();
});
};Fox Framework Middleware:
import { Middleware, Request, Response, NextFunction } from '@foxframework/core';
export class AuthMiddleware extends Middleware {
async handle(req: Request, res: Response, next: NextFunction): Promise<void> {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
const decoded = await this.jwtService.verify(token);
req.user = decoded;
next();
} catch (error) {
res.status(401).json({ error: 'Invalid token' });
}
}
}Paso 5: Actualizar Configuración
package.json scripts:
{
"scripts": {
"dev": "fox dev",
"build": "fox build",
"start": "fox start",
"test": "fox test"
}
}🔄 Migración desde Fastify
Comparación de Conceptos
| Fastify | Fox Framework |
|---|---|
fastify.register() | app.use() |
fastify.addHook() | middleware |
routes/ | controllers/ |
plugins/ | plugins/ |
Migración de Plugins Fastify
Plugin Fastify:
async function myPlugin(fastify, opts) {
fastify.decorate('myUtility', () => {
// utility logic
});
}
fastify.register(myPlugin);Plugin Fox Framework:
import { Plugin } from '@foxframework/core';
export class MyPlugin extends Plugin {
name = 'my-utility';
async install(app: FoxApplication) {
app.addUtility('myUtility', () => {
// utility logic
});
}
}
app.use(new MyPlugin());Migración de Hooks
Fastify Hooks:
fastify.addHook('preHandler', async (request, reply) => {
// logic before handler
});
fastify.addHook('onResponse', async (request, reply) => {
// logic after response
});Fox Framework Middleware:
export class RequestLifecycleMiddleware extends Middleware {
async preHandler(req: Request, res: Response, next: NextFunction) {
// logic before handler
next();
}
async postHandler(req: Request, res: Response) {
// logic after response
}
}🔄 Migración desde NestJS
Conceptos Equivalentes
| NestJS | Fox Framework |
|---|---|
@Controller() | FoxController |
@Injectable() | @Service() |
@Module() | Plugin |
Guards | Middleware |
Interceptors | Middleware |
Migración de Controllers
NestJS Controller:
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}
@Get(':id')
async findOne(@Param('id') id: string): Promise<User> {
return this.usersService.findOne(id);
}
@Post()
@UsePipes(ValidationPipe)
async create(@Body() createUserDto: CreateUserDto): Promise<User> {
return this.usersService.create(createUserDto);
}
}Fox Framework Controller:
import { FoxController, Route, Validate } from '@foxframework/core';
import { CreateUserDto } from '../dto/create-user.dto';
export class UsersController extends FoxController {
constructor(private usersService: UsersService) {
super();
}
@Route.Get(':id')
async findOne(req: Request, res: Response): Promise<void> {
const user = await this.usersService.findOne(req.params.id);
res.json({ success: true, data: user });
}
@Route.Post()
@Validate.Body(CreateUserDto)
async create(req: Request, res: Response): Promise<void> {
const user = await this.usersService.create(req.body);
res.status(201).json({ success: true, data: user });
}
}Migración de Servicios
NestJS Service:
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) {}
async findOne(id: string): Promise<User> {
return this.usersRepository.findOne({ where: { id } });
}
}Fox Framework Service:
import { Service } from '@foxframework/core';
@Service()
export class UsersService {
constructor(private usersRepository: UsersRepository) {}
async findOne(id: string): Promise<User> {
return this.usersRepository.findOne({ where: { id } });
}
}🔄 Migración desde Koa.js
Migración de Middleware
Koa Middleware:
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});Fox Framework Middleware:
export class LoggingMiddleware extends Middleware {
async handle(req: Request, res: Response, next: NextFunction): Promise<void> {
const start = Date.now();
res.on('finish', () => {
const ms = Date.now() - start;
console.log(`${req.method} ${req.url} - ${ms}ms`);
});
next();
}
}Migración de Context
Koa Context:
app.use(async ctx => {
ctx.body = { message: 'Hello World' };
ctx.status = 200;
});Fox Framework Response:
export class HelloController extends FoxController {
async hello(req: Request, res: Response): Promise<void> {
res.status(200).json({ message: 'Hello World' });
}
}🔄 Migración entre Versiones de Fox Framework
De Fox Framework 0.x a 1.x
Cambios Breaking
- API de Controllers:
// v0.x
class UserController {
async getUser(context: FoxContext) {
return context.json({ user: context.params.id });
}
}
// v1.x
class UserController extends FoxController {
async getUser(req: Request, res: Response): Promise<void> {
res.json({ user: req.params.id });
}
}- Sistema de Routing:
// v0.x
router.route('/users/:id').get(UserController, 'getUser');
// v1.x
router.get('/users/:id', userController.getUser.bind(userController));- Configuración:
// v0.x
const app = new FoxApp({
port: 3000,
database: 'postgresql://...'
});
// v1.x
const app = FoxFactory.createServer({
port: 3000,
database: {
url: 'postgresql://...'
}
});Script de Migración Automática
# Ejecutar herramienta de migración
npx @foxframework/migrate v0-to-v1
# Revisar cambios
git diff
# Ejecutar tests para verificar
npm test🔧 Herramientas de Migración
Analizador de Código
# Instalar herramientas de migración
npm install -g @foxframework/migration-tools
# Analizar proyecto actual
fox-migrate analyze
# Generar plan de migración
fox-migrate plan
# Ejecutar migración por pasos
fox-migrate step 1 # Configuración base
fox-migrate step 2 # Controllers
fox-migrate step 3 # Middleware
fox-migrate step 4 # TestingAsistente de Migración Interactivo
# Ejecutar asistente
fox-migrate interactive
# Proceso guiado:
? ¿Desde qué framework migras? Express
? ¿Versión de Express? 4.18.0
? ¿Tienes tests? Sí
? ¿Usas TypeScript? No
? ¿Migrar a TypeScript? Sí📋 Lista de Verificación Post-Migración
✅ Funcionalidad
- Todas las rutas funcionan correctamente
- Middleware personalizado migrado
- Autenticación funciona
- Base de datos conecta correctamente
- Cache funciona (si aplica)
✅ Testing
- Tests unitarios pasan
- Tests de integración pasan
- Coverage mantenido o mejorado
- Tests E2E funcionan
✅ Performance
- Tiempo de respuesta similar o mejor
- Uso de memoria optimizado
- Throughput mantenido
- Métricas configuradas
✅ Desarrollo
- Hot reload funciona
- TypeScript compila sin errores
- Linting configurado
- CI/CD actualizado
✅ Documentación
- README actualizado
- Documentación API actualizada
- Changelog creado
- Equipo entrenado
🚨 Problemas Comunes y Soluciones
Error: "Cannot find module"
# Verificar instalación
npm list fox-framework
# Re-instalar si es necesario
npm uninstall fox-framework
npm install @foxframework/core@latestMiddleware no funciona
// Verificar orden de middleware
const server = FoxFactory.createServer({
middleware: [
corsMiddleware(), // Debe ir antes que
authMiddleware(), // middleware de auth
validationMiddleware() // y validación
]
});Performance degradada
// Habilitar profiling temporalmente
import { Profiler } from '@foxframework/core';
if (process.env.NODE_ENV === 'development') {
Profiler.enable();
}Tests fallan después de migración
// Actualizar helpers de testing
import { TestingModule } from '@foxframework/testing';
// Reemplazar supertest directo
const app = await TestingModule.createTestApp();📚 Recursos de Apoyo
Documentación Específica
Soporte de la Comunidad
- Discord - Canal #migration (opens in a new tab)
- GitHub Discussions (opens in a new tab)
- Stack Overflow (opens in a new tab)
Soporte Profesional
- Migration Consulting: Ayuda profesional para migraciones complejas
- Code Review: Revisión de código post-migración
- Training: Entrenamiento para tu equipo
Contacta: migration@fox-framework.com
🎯 Próximos Pasos
Después de completar la migración:
- Optimiza tu aplicación con las nuevas características de Fox Framework
- Implementa monitoreo avanzado
- Explora plugins adicionales
- Contribuye a la comunidad compartiendo tu experiencia
¡Bienvenido a Fox Framework! 🦊