Antes de nada, a continuación tenéis el vídeo de la presentación para entender los principales conceptos que se tratan en esta guía y que se desarrolló en el Codemotion 2015.
Puesta en marcha del entorno
Como requisito antes de comenzar, es necesario tener instalado NodeJS. Para ello, recomendamos el uso de NVM (Node Version Manager), con el cual podemos instalar y utilizar varias versiones de NodeJS en nuestro entorno.
NOTA: Tenéis más información de cómo funciona y algunos ejemplos de uso en este artículo.
En definitiva, si ya tenéis NVM instalado, sólo tenéis que ejecutar:
1
$ nvm install v5.0.0
Con lo que al ejecutar los siguientes comandos, deberíais ver sin problemas las versiones correctas de NodeJS y NPM:
1 2 3 4 5
$ node -v v5.0.0
$ npm -v 3.3.6
Creación del proyecto “weather”
Nuestro objetivo en este taller va a ser migrar a React una aplicación desarrollada en jQuery que permite consultar el tiempo indicando una localidad o obteniendola de nuestra geolocalización.
El código original que vamos a migrar lo podéis descargar aquí. Como la idea es partir de la aplicación jQuery e ir haciendo cambios poco a poco, descargad ya el ejemplo para tenerlo preparado.
Listos para comenzar!! Vamos pues a crear un directorio para el proyecto y le daremos el nombre de weather-react:
Dentro del directorio del proyecto, inicializamos NPM para poder gestionar sus dependencias: ```bash $ npm init -y ```
Como vamos a ir modificando el proyecto original jQuery para ir haciendolo más "React", copiaremos todos los ficheros que habíamos descargado del proyecto original, dentro de este nuevo directorio (esto incluye los ficheros `index.html`, `weather.css` y `weather.js`).
## Integración con webpack
Antes de migrar a React el proyecto, vamos primero a poner a punto nuestro workflow de trabajo con webpack. Para ello necesitamos instalarlo:
Para comenzar a integrar nuestros ficheros JavaScript en la build, es necesario crear el fichero de configuración de webpack webpack.config.js. Partiremos de la configuración más simple posible:
<scriptsrc="weather.js"></script> ``` Por la del bundle generado por webpack:
```html <scriptsrc="bundle.js"></script> ``` Si no hemos metido la pata, todo debería seguir funcionando de la misma forma :)
Recuerda que si quieres generar la versión de producción del bundle, sólo debes ejecutar webpack con el siguiente flag:
```bash webpack -p ```
### Empaquetado de ficheros CSS
Webpack permite empaquetar y gestionar múltiples recursos al margen de los de tipo JavaScript, ofreciendo soporte también para CSS, SASS o mucho muchos más. Como en el proyecto ya tenemos nuestros estilos en un fichero CSS, vamos a incluir `weather.css` en la build.
Para ello, debemos indicar a webpack que procese estos nuevos recursos modificando su fichero de configuración: ```javascript module.exports = { entry: './weather.js', output: { filename: 'bundle.js', path: __dirname }, module: { loaders: [ { test: /\.css$/, loader: 'style!css' } ] } }
Esta nueva definición require de que los loaders style y css sean instalados previamente mediante NPM:
1 2 3 4 5 6 7 8 9 10 11
npm install --save-dev style-loader css-loader ``` Sólo nos queda pues modificar el fichero `weather.js`y hacer en su primera línea, un `require` del `weather.css`:
```javascript var styles = require('./weather.css'); var g, GLoc = { settings: { ...
Para finalizar, ya podemos eliminar la linea del index.html donde se incluye el fichero de estilos al estar ya empaquetado en el bundle.js:
Para poder comenzar a utilizar React en este proyecto, necesitamos que webpack sea capaz de procesar JSX (lenguaje con el que definiremos declarativamente las vistas en React). Esto se consigue, como en todos los casos previos, mediante la inclusión de un loader (`babel-loader` en este caso). Es importante tener en cuenta que gracias a este loader, vamos a tener acceso también a todas las novedades de ES6 (aka ES2015).
Instalemos pues las dependencias de React en primer lugar:
```bash npm install --save react react-dom
Y posteriormente, los loaders que webpack necesitará para procesar el código React:
npm install --save-dev babel-loader babel-preset-es2015 babel-preset-react ``` En este caso, también es necesaria una pequeña modificación del `webpack.config.js` para que estos nuevos loaders sean cargados:
La idea es ir migrando el código HTML/JS basado en jQuery a React de forma progresiva. Para ello vamos a definir un div que va a contener todo el código renderizado por React y que será incluido en el index.html:
1 2 3 4 5 6
... <bodyid="weather-background"class="default-weather"> <divclass="page-wrap"> <!-- Nuevo div para el output de react --> <divid="react-output"></div> ...
En el weather.js, crearé mi primera clase React que va a representar la aplicación del tiempo y comprobaré que webpack no se queja al procesar estos nuevos elementos:
Para iniciar la transformación, el primer paso será mover todo el marcado HTML que tenemos en `index.html` dentro del bloque etiquetado con el atributo `class="page-wrap"` al método render de Nuestra clase `WatherApp`:
Como podemos comprobar, todo sigue funcionando despues de este cambio.
Modularización
Aunque ya tenemos todo el marcado en una vista React, vamos a intentar partir el ejemplo en componentes más pequeños para ir aislando su funcionalidad.
Por facilidad a la hora de seguir el ejemplo, vamos a dejar todo el código en el mismo fichero, pero la práctica habitual es separa los componentes en distintos ficheros e importarlos cuando sea necesario mediante import. Gracias a webpack, todo acabará siendo incluido en nuestro bundle.js de salida.
Eventos
Llegados a este punto, sigue siendo jQuery el que gestiona los eventos que se producen en la aplicación. Vamos pues a migrar esta parte a eventos gestionado por React.
Eventos que se producen en la aplicación:
keypress cuando escribimos el nombre de la ciudad a buscar (si es un enter, entonces se ejecuta la búsqueda).
click en el botón de buscar.
click en el botón de geolocalización.
Vamos a comenzar por el primero y vamos a hacernos cargo de la gestión del evento de keypress. Pare ello deberemos borrar el código jQuery que se ocupa de actuar sobre este evento y modifcar la clase SearchBar para tratar este evento, recuperar los datos del tiempo y enviar el resultado a WeatherApp:
Ahora que tenemos el evento controlado, vamos a ocultar el mensaje de bienvenida y mostrar el bloque de info del tiempo. Para ello haremos uso de la gestión del estado de los componentes en React y modificaremos WeatherApp:
Como podemos ver, el panel cambia, pero la info del tiempo no se muestra. Vayamos pues a completar esta parte!!
Para que la información correcta se muestre, añadiremos un nuevo método al componente Info para que se pueda realizar la carga y lo invocaremos desde WeatherApp. Podemos ver como otros métodos de cálculo son necesarios en Info, pero no son más que una copia del código jQuery que ya teníamos:
Con todo el marcado migrado, los componentes React extraidos y los eventos definidos, ya sólo nos queda borrar todo el código jQuery de weather.js y comprobar que la aplicación sigue siendo funcional.
NOTA: Si has llegado hasta aquí y algo no te funciona, revisa tu código comparándolo con el que he publicado en el repo de la charla en Github.
A partir de aquí, si queremos prescindir totalmente de jQuery, podemos usar fetch para realizar las peticiones AJAX al servicio del tiempo que se usa en la aplicación. Como fetch aún no está implementado en todos los navegadores, podemos usar una librería externa que actua como polyfill. En nuestro caso vamos a utilizar isomorphic-fetch porque podemos usarla tanto en cliente como en servidor con NodeJS y soporta promesas ES6.
Para ello, instalamos como siempre las dependencias necesarias:
Si hemos integrado fetch en la aplicación, ya podemos quitar tranquilamente la dependencia de jQuery del index.html y seguir funcionando con normalidad.