Manejo de Loader y Plugins en Webpack

Esta es la continuación del tutorial anterior Primeros pasos con Webpack donde aprendimos que Webpack es una herramienta imprescindible en el desarrollo web. Pero algo que no dijimos ahí es que Webpack es completamente modular. Es decir por si solo Webpack no puede hacer nada más que unir archivos de JavaScript. Para poder darle a Webpack la capacidad de realizar determinadas tareas como unir código CSS, o transpilar código de TypeScript a JavaScript es necesario hacer uso de lo que en Webpack se conocen como Loaders y Plugins.

En este tutorial aprenderemos sobre los Loaders y Plugins, y cómo utilizarlos con Webpack para extender sus funcionalidades y agregar nuevas características a nuestros proyectos web.

Índice

  1. Instalando Loaders
  2. Instalando Plugins
  3. Carpeta de producción completa
  4. Servidor de desarrollo
  5. Agregando Git a nuestro proyecto

1. Instalando Loaders

JavaScript de forma nativa no puede importar archivos que no sean .js. O sea si quiero importar un archivo CSS desde un archivo JavaScript, no será posible hacerlo, ya que son dos lenguajes distintos. Sin embargo, gracias a Webpack esto es posible. Lo que hace webpack es interpretar el import del CSS y luego inyectarlo dentro de etiquetas <style> de tal forma que el navegador pueda entenderlo. Pero para esto necesitamos de los Loaders.

Los loaders no son más que métodos JavaScript que instalamos en webpack que se encargan de una determinada funcionalidad. En el siguiente ejemplo instalaremos un loader que nos permite encontrar el import de un archivo CSS en el código JavaScript para luego inyectarlo al código HTML de nuestro proyecto.

Primero que nada creamos un archivo .css dentro de la carpeta scr/styles/index.css para probar el loader que instalaremos. Luego dentro de nuestro archivo .js importamos el archivo CSS de la siguiente manera.

// Código de idnex.js
import ".styles/index.css";
/* Código de index.css */
body {
  background-color: aqua;
}

Si luego de hacer esto corremos nuestro comando de ejecución de Webpack, obtendremos un error ya que por defecto Webpack está agregando el código css dentro del JavaScript y se encontrará con código incompatible que no puede ejecutar. Así que ahora instalaremos nuestro primer laoder.

Otra cosa a tener en cuenta de los loaders es que no vienen con Webpack, debemos instalarlos por separado utilizando npm.

El loader que nos permite entender código css es css-loader el cual instalaremos a continuación utilizando el siguiente comando.

npm install --save-dev css-loader

Ahora debemos agregar este loader dentro de nuestra configuración de Webpack. Para eso nos dirigimos al archivo webpack.config.js en el cual agregaremos una propiedad llamada module donde agregaremos el loader que instalamos de la siguiente manera.

module: {
  rules: [
    {
      test: /\.css$/,
      use: ["css-loader"],
    },
  ];
}

Este código se interpreta de la siguiente manera:

  • Primero agregamos la propiedad module donde agregaremos nuevas reglas para webpack usando la propiedad rules.
  • Las reglas son objetos con sus respectivas propiedades, la primera regla que agregaremos es la que nos permitirá interpretar un .css y usar el css-loader.
  • La primera propiedad de la regla es test en el cual enviaremos lo que debe buscar en el código mediante una expresión regular. En nuestro caso le decimos que busque la expresión .css.
  • La segunda propiedad de la regla es use donde le enviamos mediante un arreglo los loaders que queremos que utilice cuando encuentre dicha expresión. En nuestro caso le decimos que use css-loader.

Ahora si nosotros volvemos a compilar nuestro proyecto mediante Webapack. Ya no obtendremos errores. Sin embargo, Css-loader solo se encarga de entender el código CSS, no le indica qué hacer con ese código. Para eso necesitamos otro Loader llamado style-loader. Ya ves como de modular es Webpack, que para todo se necesita de un Loader distinto. Style-loader es el que se encargará de inyectar el CSS dentro del DOM, para instalarlo solo debemos ejecutar el siguiente comando.

npm install --save-dev style-loader

Ahora solo debemos decirle a Webpack que al encontrar un .css no solo use Css-loader si no también Style-loader, para eso solo agregaremos style-loader a la propiedad use de la regla que creamos.

module: {
  rules: [
    {
      test: /\.css$/,
      use: ['style-loader', 'css-loader'],
    },
  ],
},
Para webpack es muy importante el orden en los que se llama a los Loaders. En el ejemplo anterior si cambiamos el orden de los Loader dentro del arreglo nos toparemos con un error. Asi que para webpack la posición si importa.

Style-loader inyecta los estilos al DOM usando las etiquetas<style></style> por lo que si ahora compilamos nuestro proyecto con Webpack ya seremos capaces de ver los estilos dentro de nuestra página.

Pero para probar el código necesitamos crear un archivo index.html que enlace al bundle.js para ejecutar el código resultante. Más adelante aprenderemos a generar un archivo index.html automáticamente.

2. Instalando Plugins

Los plugins nos permiten extender las funcionalidades de los loaders de tal manera que tengamos más control sobre ellos. En el ejemplo anterior vimos que Style-loader inyecto directamente en el DOM los estilos CSS. Sin embargo, muchas veces no queremos que sea así de directo y lo que buscamos es mas bien se cree un archivo CSS nuevo dentro de la carpeta public para enlazarlo con el HTML.

Pero hacer eso es una característica adicional a los loaders que solo interpretan alguna parte del código JavaScript y lo procesan como deseamos. Los plugins se encargan de tomar esa interpretación y hacer otro procesamiento sobre ellos. Por ejemplo, crear un archivo nuevo a partir de ellos. Eso es lo que buscamos ahora para nuestro código CSS, para lo cual instalaremos mini-css-extract-plugin utilizando el siguiente comando.

npm install --save-dev mini-css-extract-plugin

Luego de instalar este plugin nos dirigimos al archivo de configuración de webapack al cual haremos los siguientes cambios.

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

...

  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader,'css-loader'],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: './styles/[name].css'
    })
  ]

Este código se interpreta de la siguiente manera.

  • En primer lugar importamos mediante un require el plugin que acabamos de instalar y lo guardamos en una constante.
  • Creamos la propiedad plugins que recibirá un arreglo ya que posiblemente instalemos más plugins en el proyecto.
  • Creamos la instancia del plugin que instalamos utilizando new y la constante donde lo guardamos.
  • El constructor del plugin necesitará de un objeto como parámetro así que se lo pasamos. Este objeto recibe la propiedad filename que indica donde se creará el nuevo archivo CSS resultante.
  • Eliminamos la referencia al loader style-loader y en su lugar colocamos la instancia del plugin que estamos instalando. Los plugins son más grandes que los loaders y en su interior traen un loader para que puedan ser usados.
  • En este caso usamos el loader del plugin que acabamos de instalar para que este se encargue de interpretar el código CSS y luego enviarlo al plugin para que cree un archivo nuevo. Es por esto que utilizamos .loader.

Listo!! Si compilamos nuestro proyecto usando Webpack, se creará automáticamente una carpeta dentro de public donde se encontrará nuestro archivo main.css con nuestro código CSS.

3. Carpeta de producción completa

Nuestro proyecto aún no esta completo porque necesitamos agregar manualmente el archivo index.html en la carpeta public para enlazar el JavaScript que generamos. Pero esto no debería ser así, todos los archivos de public deben ser generados automáticamente y para eso también existe un Plugin. Este plugin es html-webpack-plugin y lo instalamos utilizando el siguiente comando.

npm install --save-dev html-webpack-plugin

Ahora debemos configurar este plugin y para esto nos dirigimos al archivo webpack.config.js donde al igual que en el mini-css-extract-plugin agregaremos el plugin a nuestro arreglo de plugins.

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  entry: path.resolve(__dirname, "src/index.js"),
  mode: "development",
  output: {
    path: path.resolve(__dirname, "public"),
    filename: "bundle.js",
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "./styles/[name].css",
    }),
    new HtmlWebpackPlugin({
      path: path.resolve(__dirname, "public"),
      title: "AndyGeek",
    }),
  ],
};

La propiedad title en el constructor de nuestro Plugin indica el titulo del HTML que se generará tras la compilación de nuestro proyecto. Ya que este plugin nos creará un archivo HTML automáticamente y por defecto estará ubicado en la carpeta del output de webpack, que en nuestro caso es public. Y por si fuera poco, ya tendrá los enlaces a los archivos CSS y JavaScript. Así que para probarlo podemos agregar el siguiente código en nuestro JavaScript y ejecutar el comando para compilar de webpack.

import "./index.css";

var div = document.createElement("div");
var text = document.createTextNode("AndyGeek");
div.appendChild(text);
document.body.appendChild(div);

Y Listo!! Ya tenemos todo una carpeta lista para irse a producción, que contiene el CSS, JavaScript y HTML para que nuestra web funcione correctamente. Sin embargo, aún es tedioso tener que compilar usando npm run build cada vez que hay cambios en el código. Para evitarnos esto existe el modo watch de Webpack. Este modo nos servirá para que Webpack compile nuestro proyecto cada vez que guardamos algún cambio en el código.

Para usar este modo solo debemos crear un nuevo script para que ejecute Webpack usando este modo. Así que usaremos build:w para ejecutar el modo watch de Webpack.

"build:w" : "webpack -w"

Y por fin ya estamos comprendiendo cada vez más todo lo que hace un framework como Vuejs o React por debajo para lograr las fabulosas funcionalidades que traen consigo. Aunque es interesante saber que estos frameworks no utilizan el modo watch de Webpack, si no más bien un servidor de desarrollo. A continuación veremos que es y cómo utilizar esta herramienta en nuestro proyecto web.

4. Servidor de desarrollo

Un servidor de desarrollo es un servidor que se ejecuta con nuestro proyecto de manera local, y de esta forma podemos ver los cambios de nuestro proyecto casi en tiempo real ya que mantendrá a la página ejecutándose tal y como un servidor web. Pero, como de seguro ya te lo imaginaste por la modularidad de la filosofía Webpack, este servidor es una herramienta a parte llamada webpack-dev-server, el cual lo instalamos usando el siguiente comando.

npm install --save-dev webpack-dev-server

Webpack-dev-server trae consigo un CLI que nos permitirá ejecutar el siguiente comando para correr nuestro proyecto en un servidor local.

npx webpack-dev-server

Y para facilitarnos las cosas podemos colocar este comando dentro de un Script en el package.json para llamar a su ejecución de forma más rápida.

"dev": "webpack-dev-server"

Entonces si ahora ejecutamos el comando npm run dev nuestro código se compilará creando una carpeta public y también podremos ver corriendo nuestro proyecto usando el servidor de producción que instalamos solo debemos ingresar al siguiente enlace.

Es importante saber que webpack-dev-server no generá el código en la carpeta public. Lo que hace es generar el código de forma temporal y en alguna carpeta externa para luego ejecutarlo con el servidor. Pero no genera el código final para producción. Es por esta razón que se deben tener dos scripts. Uno para construir la carpeta public para mandarlo a producción y otro para ver los cambios con el servidor de desarrollo.

5. Agregando Git a nuestro proyecto

Para agregar Git a nuestro proyecto primero que nada debemos tener Git instalado en nuestra computadora, podemos conseguir el instalador desde la web oficial de git. Luego de la instalación de Git, que es relativamente fácil, ya podremos usar sus comandos desde la consola. Para ver si Git se instaló correctamente usamos el siguiente comando.

git --version

Para agregar git a nuestro proyecto debemos ejecutar el siguiente comando ubicándonos con la terminal dentro de la carpeta raíz de nuestro proyecto.

git init

Después de esto debemos agregar un archivo llamado .gitignore donde agregaremos los archivos y carpetas que queremos que git ignore y no los agregé al repositorio. Estos archivos y carpetas generalmente son las dependencias instaladas, ya que estas dependencias pesan mucho y se pueden instalar a partir de la información del package.json utilizando el comando npm intall. Así que en el archivo .gitignore agregamos el siguiente código.

node_modules/
.vscode/

Lo primero que estamos ignorando para git es la carpeta node_modules donde estan instalados todas las dependencias de npm. La segunda carpeta que ignoramos es .vscode que contiene metadatos que Visual Studio Code crea para nuestro proyecto. Este último es opcional si todas las personas involucradas en el proyecto usan VSCode como editor de código. Pero podría ser irrelevante si cada uno usa un editor de código diferente.

Luego de crear el .gitignore ya podemos crear los commits a nuestro proyecto. Así que a continuación agregaremos nuestro primero commit.

git add -A
git commit -m "Upload project"

Para luego subir el proyecto hacia algún repositorio online como GitHub o Gitlab usando los siguientes comando.

git remote add origin https://github.com/user/repo.git
git push origin master

Con esto ya tendremos nuestro proyecto en un repositorio online como GitHub. Yo generalmente uso GitHub y el repositorio de este proyecto es github.com/andygeek/webpack-app

Y así llegamos al final de este tutorial donde aprendimos a utilizar los Loaders y Plugins de Webpack para agregar herramientas de desarrollo a nuestros proyecto. Además estamos aprendiendo como es que funciona un framework como React o Vuejs por dentro. Así que te espero en el próximo tutorial donde descubriremos más sobre Webpack. Soy Andy Geek y hasta un próximo tutorial 😁