Menu
CoddyTech

Archivos estáticos

Parte de la sección Conceptos básicos de Express del Journey de Node.js de Coddy. Lección 11 de 23.

Una hoja de estilos o una imagen nunca cambia, y crear una ruta para cada archivo sería trabajo innecesario.

app.use(express.static('assets'));

express.static('assets') sirve los archivos de la carpeta assets usando sus propios nombres: assets/logo.png responde a GET /logo.png. El nombre de la carpeta no forma parte de la URL. Express determina el tipo de contenido según la extensión: text/css para .css, image/png para .png. Si una ruta no tiene archivo, la solicitud pasa a tus rutas.

app.use agrega una función que se ejecuta para cada solicitud; el próximo capítulo trata sobre esas funciones. Ahora tu proyecto tiene una carpeta public con una hoja de estilos.

challenge icon

Desafío

Fácil

Recipe Box ahora tiene una hoja de estilos. El archivo está listo en la carpeta public; tu servidor solo tiene que servirlo.

  1. En server.js, justo después de const app = express();, sirve todos los archivos de la carpeta public con express.static. Después, public/style.css se sirve en /style.css.
  2. Haz que la página de inicio la cargue: coloca <link rel="stylesheet" href="/style.css"> al principio del HTML que envía la ruta /.

Pruébalo: Pulsa «Jugar» y envía /. La página ahora usa la hoja de estilos. Envía /style.css: estado 200, el texto CSS y un Content-Type de text/css en la pestaña Headers. Envía /missing.css: no existe ese archivo, así que la solicitud pasa a tus rutas. Ninguna coincide y Express responde con 404.

Pruébalo tú mismo

import {escapeHtml} from './html.js';
import express from 'express';
import { recipes } from './data.js';

const app = express();



app.get('/', (req, res) => {
    const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
    res.send(`<h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});

// type('text') envía texto sin formato, por lo que cada título aparece en su propia línea.
app.get('/recipes', (req, res) => {
    const { tag } = req.query;
    const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
    res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});

app.get('/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).send('No such recipe');
        return;
    }
    res.send(recipe.title);
});

app.get('/api/recipes', (req, res) => {
    res.json(recipes);
});

app.get('/api/recipes/:id', (req, res) => {
    const recipe = recipes.find((r) => r.id === Number(req.params.id));
    if (!recipe) {
        res.status(404).json({ error: 'No such recipe' });
        return;
    }
    res.json(recipe);
});

app.get('/about', (req, res) => {
    res.send('Recipe Box collects family recipes.');
});

app.listen(3000, () => {
    console.log('Recipe Box is running on port 3000');
});

Todas las lecciones de Conceptos básicos de Express

Practica por tu cuenta: Playground de Express