La estructura del directorio para compartir archivos desde el backend, tanto de forma estática como dinámica, debe estar organizada para facilitar el mantenimiento y la escalabilidad del proyecto con Node.js. Aquí tienes un ejemplo de cómo podrías estructurarlo:
proyecto/
├── backend/
│ ├── controllers/ # Controladores para manejar las peticiones dinámicas
│ ├── models/ # Modelos para interactuar con la base de datos
│ ├── routes/ # Definición de las rutas de tu API
│ ├── middlewares/ # Middlewares personalizados
│ ├── utils/ # Funciones de utilidad
│ ├── config/ # Configuración de la app (e.g., variables de entorno)
│ ├── server.js # Archivo principal del servidor backend
│
├── frontend/
│ ├── public/ # Archivos estáticos (HTML, CSS, imágenes, etc.)
│ ├── src/ # Código fuente del frontend (React, Angular, etc.)
│ ├── components/ # Componentes del frontend
│ ├── assets/ # Recursos (imágenes, fuentes, íconos, etc.)
│ ├── styles/ # Archivos CSS/SASS
│ ├── app.js # Punto de entrada del frontend
│
├── uploads/ # Carpeta para almacenar archivos subidos dinámicamente
├── logs/ # Archivos de logs del servidor
├── node_modules/ # Dependencias instaladas por npm
├── package.json # Archivo de configuración del proyecto
├── .env # Variables de entorno
Detalles clave:
Archivos estáticos (Frontend):
Coloca los archivos estáticos en la carpeta
frontend/public
. El backend puede servir esta carpeta
utilizando algo como express.static
(en el caso de
Node.js).
Archivos dinámicos (Uploads):
Los archivos subidos por los usuarios, como imágenes o documentos,
pueden almacenarse en una carpeta específica como
uploads/
. Puedes crear rutas específicas en el backend
para manejar la subida y la recuperación de estos archivos.
Seguridad: Limita el acceso público a directorios sensibles. Por ejemplo, los
contenidos de uploads/
deben ser accesibles a través de rutas
del backend controladas, no directamente desde el navegador.
Flexibilidad: Mantén separadas las responsabilidades del backend y el frontend. Esto te permitirá escalar el proyecto fácilmente si decides dividirlos en servicios independientes.
Estructura del Proyecto
Aquí tienes el código fuente para cada archivo clave de la estructura. Puedes copiar y crear los archivos en tu proyecto local
Backend
server.js Archivo principal del servidor.
const express = require('express');
const path = require('path');
const routes = require('./routes/index');
const app = express();
// Middleware para servir archivos estáticos
app.use(express.static(path.join(__dirname, '../frontend/public')));
// Middleware para manejar JSON
app.use(express.json());
// Rutas dinámicas
app.use('/api', routes);
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Servidor corriendo en http://localhost:${PORT}`);
});
routes/index.js: Define las rutas de tu API.
const express = require('express');
const router = express.Router();
const { getData } = require('../controllers/dataController');
router.get('/data', getData);
module.exports = router;
controllers/dataController.js: Controladores para peticiones dinámicas.
exports.getData = (req, res) => {
res.json({ mensaje: '¡Hola desde el backend dinámico!' });
};
Frontend
frontend/public/index.html: Página principal del frontend.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Frontend + Backend</title>
<link rel="stylesheet" href="/styles/main.css">
</head>
<body>
<h1>¡Hola desde el Frontend!</h1>
<button id="fetchDataBtn">Obtener Datos</button>
<div id="dataDisplay"></div>
<script src="/app.js"></script>
</body>
</html>
frontend/public/styles/main.css: Estilos.
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 0;
padding: 20px;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
frontend/public/app.js: Lógica del frontend.
document.getElementById('fetchDataBtn').addEventListener('click', async () => {
const response = await fetch('/api/data');
const data = await response.json();
document.getElementById('dataDisplay').textContent = data.mensaje;
});
Pasos para Ejecutar el Proyecto
1- Clonar la estructura: Crea las carpetas y archivos siguiendo el esquema mostrado arriba.
2- Instalar dependencias: En la raíz del proyecto, ejecuta:
npm init -y
npm install express
3- Ejecutar el servidor: Ejecuta el backend con:
node backend/server.js
4- Abrir en el navegador: Accede a http://localhost:3000 para ver el frontend y probar la conexión con el backend.
Archivos dinámicos (Uploads):
Ejemplo de subida de archivos en
const multer = require('multer');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
cb(null, `${Date.now()}-${file.originalname}`);
},
});
const upload = multer({ storage });
app.post('/upload', upload.single('archivo'), (req, res) => {
res.json({ mensaje: 'Archivo subido correctamente.', archivo: req.file });
});
Puedes agregar este código en tu archivo principal del servidor, server.js, o modularizarlo en una carpeta específica como routes/ para mantener tu proyecto organizado. Aquí está cómo podrías integrarlo:
1. Crear la Carpeta uploads/
-
Asegúrate de crear manualmente la carpeta
uploads/
en la raíz del proyecto. Esta es la ubicación donde se almacenarán los archivos subidos.
2. Instalar Multer
-
Necesitas instalar la dependencia
multer
antes de usar el código. Ejecuta el siguiente comando en tu terminal:
npm install multer
3. Agregar el Código en server.js
(Opción Simple)
Si quieres agregarlo directamente en server.js
, puedes
colocarlo después de configurar el middleware y antes de iniciar el
servidor:
const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();
// Configurar Multer para subir archivos
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/'); // Carpeta donde se almacenan los archivos
},
filename: (req, file, cb) => {
cb(null, `${Date.now()}-${file.originalname}`); // Nombra los archivos con la fecha y el nombre original
},
});
const upload = multer({ storage });
// Middleware para servir archivos estáticos
app.use(express.static(path.join(__dirname, '../frontend/public')));
// Ruta para subir archivos
app.post('/upload', upload.single('archivo'), (req, res) => {
res.json({
mensaje: 'Archivo subido correctamente.',
archivo: req.file,
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Servidor corriendo en http://localhost:${PORT}`);
});
4. Modularizar el Código (Opción Más Organizada)
Si prefieres modularizar, sigue estos pasos:
-
Crea un Archivo en
routes/uploads.js
:
const express = require('express');
const multer = require('multer');
const router = express.Router();
// Configuración de Multer
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
cb(null, `${Date.now()}-${file.originalname}`);
},
});
const upload = multer({ storage });
// Ruta para subir archivos
router.post('/', upload.single('archivo'), (req, res) => {
res.json({
mensaje: 'Archivo subido correctamente.',
archivo: req.file,
});
});
module.exports = router;
Registra las Rutas en server.js:
const express = require('express');
const path = require('path');
const uploadRoutes = require('./routes/uploads');
const app = express();
app.use(express.static(path.join(__dirname, '../frontend/public')));
app.use('/upload', uploadRoutes);
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Servidor corriendo en http://localhost:${PORT}`);
});
5. Probar la Subida de Archivos
- Usa una herramienta como Postman para probar la ruta de subida. Haz una solicitud POST a
http://localhost:3000/upload
con un archivo (clave del campo:archivo
).
- Verifica que el archivo aparece en la carpeta
uploads/
.