Estas notas explican como crear una aplicación web que utiliza Express para el back-end y React.js para el front-end.

La aplicación a construir permitirá desplegar refranes aleatorios al presionar un botón:

App

1. Configuración inicial

  1. Crear una aplicación de Express con los siguientes comandos desde la terminal:

    express --view=ejs refranes
    cd refranes
    npm install
  2. Instalar el compilador de babel para poder utilizar JSX en nuestro proyecto. En la terminal dentro del directorio refranes teclear:

    npm install babel-cli@6 babel-preset-react-app@3 --save

    Crear el directorio react_src para guardar los archivos fuentes de React.

    mkdir react_src

    Abrir en el editor el archivo package.json y agregar la propiedad "babel" al objeto asociado a "scripts" con el siguiente valor: "npx babel --watch react_src --out-dir public/javascripts --presets react-app/prod". El archivo package.json se debe ver así ahora:

    {
      "name": "refranes",
      "version": "0.0.0",
      "private": true,
      "scripts": {
        "start": "node ./bin/www",
        "babel": "npx babel --watch react_src --out-dir public/javascripts --presets react-app/prod"
      },
      "dependencies": {
        "babel-cli": "^6.26.0",
        "babel-preset-react-app": "^3.1.2",
        "cookie-parser": "~1.4.4",
        "debug": "~2.6.9",
        "ejs": "~2.6.1",
        "express": "~4.16.1",
        "http-errors": "~1.6.3",
        "morgan": "~1.9.1"
      }
    }

    Ahora, para poder correr el compilador de babel es necesario teclear en la terminal el siguiente comando (en el directorio refranes) y dejarlo corriendo mientras estemos escribiendo código de React:

    npm run babel

    Cualquier archivo que con extensión .jsx o .js (JSX o ECMAScript 6 o superior) que sea creado y/o modificado en el directorio react_src automaticamente será traducido a ECMAScript 5 y el archivo resultante se colocará en el directorio public/javascripts.

2. Back-end: API web de refranes

  1. Crear un archivo JSON llamado refranes.json y guardarlo en el directorio routes. Copiar el siguiente contenido a dicho archivo:

    Archivo: routes/refranes.json
    [
      "¡A darle que es mole de olla!",
      "Agua que no has de beber, déjala correr.",
      "Al nopal sólo se le arriman cuando tiene tunas.",
      "Botellita de jerez, todo lo que me digas será al revés.",
      "Sale más caro el caldo que las albóndigas.",
      "Dando y dando, pajarito volando.",
      "El que con lobos anda, a aullar se enseña.",
      "El que es perico, donde quiera es verde.",
      "Ni tanto que queme al santo, ni tanto que no lo alumbre.",
      "Dime de qué presumes y te diré de qué careces.",
      "Árbol que nace torcido, jamás su tronco endereza.",
      "El hombre propone, Dios dispone, llega el diablo y todo descompone.",
      "Crea fama y échate a dormir.",
      "Más sabe el diablo por viejo, que por diablo.",
      "Al buen entendedor, pocas palabras."
    ]
  2. Añadir al final del archivo routes/index.js las siguientes líneas de código:

    Archivo: routes/index.js
    const refranes = require('./refranes.json');
    
    router.get('/refran', (req, res) => {
      const refran = refranes[(Math.random() * refranes.length) | 0];
      res.json({ refran });
    });
  3. Para probar el API web, ejecutar el servidor. Desde la terminal teclear:

    npm start

    Sin terminar la ejecución del servidor, abrir otra terminal y correr el siguiente comando:

    curl -i localhost:8080/refran

    La salida debe ser algo así (puede ser distinta ya que es aleatoria):

    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: application/json; charset=utf-8
    Content-Length: 54
    ETag: W/"36-pw1bYjKBmzzBjqmaW1aSRd+seoQ"
    Date: Fri, 27 Mar 2020 04:22:02 GMT
    Connection: keep-alive
    
    {"refran":"Agua que no has de beber, déjala correr."}

3. Front-end: La interfaz de usuario

  1. Crear un archivo llamado refranes.html y colocarlo en el directorio public. El contenido de este archivo debe ser el siguiente:

    Archivo: public/refranes.html
    <!DOCTYPE html>
    
    <html lang="es">
    
      <head>
        <meta charset="utf-8" />
        <meta name="viewport"
              content="width=device-width, initial-scale=1">
        <title>Refranes</title>
        <link rel="stylesheet"
              href="https://www.w3schools.com/w3css/4/w3.css">
        <script src="https://unpkg.com/react@16/umd/react.development.js">
        </script>
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js">
        </script>
      </head>
    
      <body>
        <div id="root"></div>
        <script src="/javascripts/refranes.js"></script>
      </body>
    
    </html>
  2. Crear un archivo de React llamado refranes.jsx en el directorio react_src. El contenido de este archivo debe ser:

    /* global React, ReactDOM, fetch */
    
    const Cabeza = () => (
      <div className="w3-bar w3-teal">
        <div className="w3-container">
          <h1>
            Refranes aleatorios
          </h1>
        </div>
      </div>
    );
    
    const Pie = () => (
      <footer className="w3-container w3-center w3-small">
        <span className="w3-mobile">
          &copy; 2020 por Pepper Pots (A01166611)
        </span>
      </footer>
    );
    
    const Texto = props => (
      <div className="w3-panel w3-sand w3-card-4">
        <p>
          <em>{props.mensaje}</em>
        </p>
      </div>
    );
    
    class Aplicacion extends React.Component {
    
      constructor(props) {
        super(props);
        this.state = {
          mensaje: 'Presiona el botón para obtener un refrán al azar.'
        };
        this.cliquea = this.cliquea.bind(this);
      }
    
      cliquea() {
        fetch("/refran")  // llamada de AJAX
          .then(res =>
            res.json())
          .then(
            result => {
              this.setState({
                mensaje: result.refran
              });
            },
            error => {
              this.setState({
                mensaje: error.message
              });
            }
          );
      }
    
      render() {
        const { mensaje } = this.state;
        return (
          <div>
            <Cabeza />
            <div className="w3-container">
              <Texto mensaje={mensaje} />
              <p>
                <button className="w3-button w3-black w3-round-xlarge"
                        onClick={this.cliquea}>
                  Genera refrán
                </button>
              </p>
            </div>
            <hr />
            <Pie />
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <Aplicacion />,
      document.getElementById('root')
    );
  3. Es importante que tanto el servidor de node (npm start) como el compilador de babel (npm run babel) estén corriendo en sus propias terminales.

    Del menú de Cloud9 seleccionar Preview / Preview Running Application. Al URL de la página que se abre se le debe añadir /refranes.html al final.

    Si todo se realizó correctamente, la aplicación web debe verse en el navegador. Cada vez que se presione el botón debe aparecer un refrán al azar.