React : Babel + Webpack + Sass aplicación básica


Introducción

En este tutorial veremos como construir una aplicación React con Webpack, Babel y Sass.

El principal requisito para este tutorial es disponer de una instalación para tu plataforma/sistema operativo de node con npm.

El tutorial está estructurado en varias secciones:

  • Crear un directorio con un proyecto inicial en blanco
  • Instalar Webpack
  • Instalar Babel
  • React
  • Añadir soporte para estilos con Sass

Proyecto Inicial

El primer paso es crear un proyecto inicial en blanco. Para ello crearemos un directorio para el proyecto y ejecutaremos el siguiente comando dentro del mismo:

Este comando creará un nuevo fichero package.json con los metadatos por defecto para un nuevo proyecto.

Las partes relevantes del fichero package.json generado deberían de actualizarse con los valores que consideremos para el nuevo proyecto. Este es el contenido de nuestro fichero tras las modificaciones iniciales:

Webpack: añadir soporte para Webpack 4

Instalar Webpack

El siguiente paso es añadir soporte para Webpack.

El comando anterior añadirá Webpack a las dependencias de desarrollo de nuestro fichero package.json. Las tres primeras están estrictamente relacionadas con Webpack, si has trabajado con Webpack en otros proyectos, probablemente las tengas instaladas como dependencias globales. Para nuestro propósito y con motivo de soportar diferentes versiones de Webpack, las añadimos como dependencias locales.

Las otras dos (html-webpack-plugin, html-loader) se emplearán para minimizar el código html generado y para poder hacer referencia al Javascript empaquetado de nuestra aplicación.

Tras la ejecución del comando, en nuestro fichero package.json se habrá creado una nueva sección "devDependencies".

Configuración de Webpack

El primer paso es crear contenido/código fuente para que Webpack pueda procesarlo. Creamos un nuevo directorio para alojar el código fuente  y un fichero index.html dentro de este directorio con el siguiente contenido:

Para que Webpack (4) funcione necesitaremos un fichero de configuración para webpack. Para ello creamos un fichero webpack.config.js vacío en el directorio raíz del proyecto y le insertamos este contenido:

En la primera sección añadimos los require del script y declaramos dos constantes (SRC_DIR, DIST_DIR) para hacer referencia a los directorios con las fuentes (src) y la aplicación construida (dist).

A continuación declaramos un nuevo módulo empleando como punto de entrada el fichero index.html creado en el paso anterior. Los ficheros de salida del módulo (output) se generarán en un directorio con el nombre ./dist. Cuando el proyecto se construya una versión minimizada del fichero index.html y otro con el nombre bundle.js se generarán dentro de este directorio.

En la sección de reglas (rules) añadiremos el primer loader. En este caso vamos a usar html-loader para preprocesar todos los ficheros html ubicados en el directorio src.

Queda por rellenar la configuración para resolve extensions. Esta configuración nos permitirá hacer referencia en los scripts a otros ficheros/dependencias indicando únicamente el nombre de fichero sin la extensión. En este caso, cuando en nuestro código indiquemos un import import Component from ./feature/Component' Webpack buscará el código fuente del componente en  ./feature/Component./feature/Component.js and ./feature/Component.jsx.

En la sección de plugins vamos a incluir el plugin de Webpack HotModuleReplacementPlugin que se encarga de a cambiar, añadir o quitar módulos mientras la aplicación se está ejecutando sin necesidad de hacer una recarga completa cuando se realice cualquier modificación en el código fuente (hot reloading).

También añadiremos el plugin HtmlWebpackPlugin que se encargará de hacer referencia al fichero con el paquete de javascript (bundle) en el fichero index.html creado anteriormente.

Por último definiremos un servidor de desarrollo (devServer) para servir nuestro módulo con hot reloading en el puerto 9000.

package.json webpack scripts

El último paso para poner en marcha Webpack es definir algunos scripts en el fichero package.json para que la aplicación se pueda construir y servir:

El primero de ellos (npm run build) ejecutará el proceso de construcción de la aplicación depositando dos ficheros en el directorio dist: index.html y bundle.js. Estos ficheros ya podrían desplegarse en un servidor web de estáticos sin que fuese necesaria ninguna otra configuración.

El segundo de los scripts (npm start) lanzará un servidor de desarrollo con el módulo compilado en memoria y reaccionando a posibles cambios en el código. Una vez invocado con éxito, podemos dirigir nuestro navegador a la URL http://localhost:9000 dónde la aplicación ya debería de estar disponible. Cualquier cambio en el código fuente debería de desencadenar una recarga del navegador mostrando los nuevos cambios.

Es conveniente notar como hemos definido los scripts haciendo referencia a la versión local de webpack client (./node_modules/.bin/webpack) en lugar de a la a versión global  (webpack) que probablemente también esté disponible en el sistema. Esto nos va a permitir controlar y ejecutar una versión específica de Webpack en este proyecto, ejecutando aquella versión que se haya definido en la sección devDependencies del fichero de configuración package.json.

Babel: añadir soporte para Babel

Instalar Babel

Una vez disponemos de un proyecto en el que hemos configurado Webpack el siguiente paso es añadir soporte para Babel. Babel se encargará de transpilar JSX y Javascript en Javascript compatible con ES5. React recomienda desarrollar el código empleando la sintaxis JSX ya que permite mezclar código HTML y Javascript de forma sencilla.

El comando anterior añadirá Babel a las dependencias de desarrollo (devDependencies) del fichero package.json. El paquete babel-core añadirá el soporte básico para Babel. babel-loader habilitará la ejecución de Babel desde Webpack. babel-preset-env añadirá soporte para transpilar Javascript > ES5. babel-preset-react añadirá soporte para transpilar ficheros con sintaxis JSX

Configuración de Babel

Una vez tenemos Babel instalado, debemos de configurar Babel para que utilice los dos presets que hemos instalado en el paso anterior. Para ello debemos de crear un fichero .babelrc con el siguiente contenido:

A continuación debemos de configurar Webpack para que utilice el loader de Babel para que preprocese los ficheros jsx y js antes de empaquetarlos. Para ello insertaremos la siguiente regla en la sección  module rules de nuestro fichero webpack.config.js:

A partir de este momento cuando cualquiera de los scripts de Webpack que hemos definido previamente se ejecute, Babel se arrancará y transpilará los ficheros js y jsx empleando los presets definidos en el fichero .babelrc.

React

Instalar React

Para poder utilizar React en nuestros proyectos debemos de añadir dos nuevos paquetes:

El comando anterior añadirá React a las dependencias de nuestro fichero package.json.

Punto de entrada (Entrypoint) de la aplicación

Una vez tenemos disponibles las dependencias de React, vamos a crear el punto de entrada de nuestra aplicación React. Para ello crearemos un nuevo fichero index.jsx dentro del directorio src con el siguiente contenido:

Este fichero renderizará <p>Hello world</p> dentro del tag <div  id="root"... en el fichero index.html que hemos creado en el paso anterior.

Desde este momento, ya podemos lanzar el script empleando el comando npm start y acceder a nuestra aplicación apuntando el navegador a http://localhost:9000/.

React Hello World in browser

Hot Module Replacement

Nuestra aplicación incluye el plugin de Webpack Hot Module Replacement (HMR). Este plugin modifica, añade o quita módulos de una aplicación mientras se está ejecutando sin necesidad de lanzar una recarga completa. Este mejora mucho el rendimiento y la productividad ya que los cambios en el código fuente se muestran casi al instante en el navegador sin necesidad de redesplegar la aplicación.

Cualquier cambio en el código de un fichero lanzará una recarga automática en el navegador y los cambios se mostrarán enseguida.

El único inconveniente de HMR es que no preserva el estado de la aplicación. En otro post analizaremos cómo podemos emplear React Hot Loader para incrementar aun más la productividad en el desarrollo de la aplicación al preservar el estado de la aplicación cuando se hace una recarga en caliente.

React App Component

Con el fin de mantener el código estructurado vamos a añadir el primer componente a la aplicación y a anidarlo bajo el fichero principal index.jsx. Para ello crearemos un fichero app.jsx con el siguiente contenido;

Ahora incluiremos el import del nuevo componente en el fichero index.jsx (import App from "./app";) y añadiremos el componente:

SCSS: añadir soporte para Sass

A pesar de que React ofrece diferentes formas para dar estilo a los componentes y de que existen infinidad de librerías con estilos para componentes, personalmente encuentro muy práctico el uso de CSS clásico o Sass para dar estilo a nuestra aplicación. Uno de los principales motivos es que Sass me permite compartir variables, media queries, partials, mixins…. de forma eficiente en todos los componentes de la misma aplicación e incluso entre diferentes repositorios con frameworks distintos (Puedo compartir la misma librería SCSS entre distintas aplicaciones construidas con diferentes frameworks: React, Angular, Hugo…).

Configuración de SCSS

Para poder preprocesar los ficheros SCSS tendremos que añadir algunos loaders más a Webpack, además de los bindings para node del preprocesador de Sass LibSass (node-sass):

mini-css-extract-plugin se encargará de extraer todo el código CSS generado en un único fichero. css-loader se responsabilizará de los módulos CSS (explicado más adelante) y de resolver los estilos dentro de nuestros componentes React. sass-loader and node-sass harán el preprocesado de los ficheros Sass compilando/convertiendo el código SCSS en CSS.

Una vez instaladas las dependencias de desarrollo, añadimos una nueva regla a la sección module rules de nuestro fichero webpack.config.js para invocar los loaders que acabamos de añadir.

En la nueva regla hacemos referencia a los 3 loaders que hemos instalado en el paso anterior. Para el caso de css-loader añadimos una configuración adicional para dar soporte a los módulos CSS (explicado más adelante).

También debemos de añadir una referencia y configuración a MiniCssExtractPlugin  en la sección de plugins (revisa el fichero webpack.config.js completo para ver los imports y las declaraciones de constantes);

En las líneas anteriores se define la configuración del plugin MiniCssExtractPlugin y como debe de generarse el fichero con el paquete CSS.

SCSS global

Para organizar los estilos globales de la aplicación crearemos la siguiente estructura de directorios:

El fichero main.scss contiene los imports para los ficheros con los partials. A modo de ejemplo hemos incluido 3 ficheros con Sass partials: _variables.scss para declarar las variables con los colores, fuentes, etc.; _mixins.scss que incluye un mixin de muestra para hacer una caja redimensionable; y _base.scss que define los estilos básicos para la aplicación.

Finalmente, para habilitar los estilos globales en la aplicación tendremos que añadir un import al fichero de estilos principal main.scss dentro de nuestro componente app.jsx. Esto será tan sencillo como añadir la siguiente línea en la sección de imports del componente: import styles from './styles/main.scss';. Webpack automáticamente reconocerá el import durante la fase de transpilación resolviendo la ubicación del fichero empaquetado con los estilos completos empleando la regla para el módulo que hemos definido en el paso anterior.

CSS Modules: Módulos CSS para dar estilo a cada componente

En la sección anterior hemos visto como declarar estilos globales para nuestra aplicación, en ésta veremos como utilizar los módulos CSS para permitir dar estilos SCSS independientes a cada componente React.

En el fichero webpack.config.js ya hemos declarado una regla para el preprocesado de estilos SCSS y la configuración de css-loader. Para permitir los módulos CSS además hemos añadido configuración adicional: modules: true and localIdentName que definen la forma en la que el nombre de las clases CSS se extenderán. En definitiva, con el enfoque de los módulos CSS, lo que ocurrirá cuando se genere el código de la aplicación es que se añadirá un hash a los nombres de las clases que definamos en el código.

Para demostrar como funciona esto vamos a crear dos componentes (Button and FancyButton), ambos con el mismo código y nombre de clases CSS, pero definidos en ficheros diferentes. Gracias al enfoque modular, cada uno de ellos se mostrará con su diseño particular.

Para cada componente vamos a añadir un fichero jsx con su definición:

Ambos botones tendrán el mismo código, siendo la única diferencia el nombre de la clase Javascript. Para poder hacer referencia al nombre de la clase definida en el código SCSS de cada componente, utilizaremos  {styles.button},  donde styles es la referencia al fichero SCSS definida en la sección de imports y button es el nombre de la clase CSS definida dentro de este fichero (button para ambos).

También añadiremos un fichero SCSS con los estilos para cada uno de los componentes:

De nuevo, para ambos componentes, tanto la estructura como el nombre de la clase CSS serán iguales para ambos botones. La única diferencia serán los estilos particulares para cada uno de ellos.

Por último añadimos los dos botones al componente App:

Cuando la página se muestre en el navegador, aunque ambos componentes comparten el mismo nombre de clase CSS, cada uno de ellos se renderiza con los estilos que tiene definido en su propio fichero SCSS.

Si inspeccionamos el nombre de las clases de cada uno de los botones, veremos que ambos tienen el mismo nombre (button) per con un sufijo diferente consistente en un hash añadido por css-loader:

Conclusión

Esta publicación es un tutorial para crear una aplicación React básica con soporte para estilos Sass, Babel y Webpack 4. El tutorial muestra como instalar todas las dependencias y como configurar Webpack y Babel para transpilar los fichero React jsx en código Javascript estándar. En la última sección se incluyen instrucciones para añadir estilos Sass tanto a nivel global de aplicación como a nivel particular de componente empleando CSS modules. La intención de esta publicación es disponer de una pequeña guía para crear la estructura básica de una aplicación cada vez que se inicie un nuevo proyecto React.

El código fuente completo de este artículo puede encontrarse en Github.

react webpack babel sass mn

Dejar un Comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *