Webpack para torpes 🧐
Tags: webdev, javascript, webpack, spanish
Published: 2021-10-18 16:03:27

# **Índice**
1. [Requerimientos para aprender Webpack](#id1)
2. [¿Qué es webpack?](#id2)
3. [¿Por qué es útil empaquetar nuestro código?](#id3)
4. [Webpack 5](#id4)
5. [Instalación](#id5)
6. [webpack.config.js](#id6)
7. [Puntos clave de webpack](#id7)
8. [Referencias](#id8)
9. [Conclusiones](#id9)


## **Requerimientos para aprender Webpack**<a name="id1"><a/>
Webpack al ser una tecnología web más avanzada resultará complejo y hasta frustrante tratar de estudiarlo y comprenderlo sin tener conocimientos previos, se recomienda mínimamente saber los siguientes puntos:
* **HTML5**
* **CSS3**
* **Javascript moderno** (**ES6** para adelante)
* Conceptos básicos de **Node.js** (no necesario pero sí muy útil)

## **¿Qué es webpack?**<a name="id2"><a/>
Según la [documentación oficial](https://webpack.js.org/concepts/), **webpack es un empaquetador de módulos estáticos para apps javascript**
Entiéndase por módulos estáticos archivos:
* Archivos `.js`,
* Código `.css` puro o usando preprocesadores como `sass`, `less`, `post-css`, etc.
* Imágenes en diferentes formatos: `.png`, `.jpg`, etc.
* Motores de plantillas como `pug`.

## **¿Por qué es útil empaquetar nuestro código?**<a name="id3"><a/>
Motivos por los cuales usar webpack es una buena idea:
* Tienes un entorno de desarrollo más productivo.
* Webpack permite administrar todos los archivos estáticos del proyecto de una manera más eficiente.
* Es ampliamente usado por frameworks y librerías frontend actuales como **React**, **Angular** o **Vue**.
* Permite modificar nuestro código y prepararlo para hacer deploy en producción.
* Permite usar **imports** y **exports** de javascript moderno para la gestión de nuestro código javascript de manera simple.
* Es **extensible** y **modular**, a medida que necesitamos más funcionalidades podemos configurarlo para que se adapte a las necesidades del proyecto.

![img](https://www.campusmvp.es/recursos/image.axd?picture=/2017/4T/Webpack-Concepto.gif)

## **Webpack 5**<a name="id4"><a/>
El 10 de octubre de 2020 se liberó la versión 5 de webpack, esta versión es la más actual y las más estable por lo que para nuevos proyectos se recomienda usar esta. Puedes encontrar mas informacion sobre esta actualizacion (preguntas frecuentes, como migragrar de webpack 4 a webpack 5, etc) obviamente en la [documentación oficial](https://webpack.js.org/blog/2020-10-10-webpack-5-release/)

## **Instalación**<a name="id5"><a/>
Para su correcto funcionamiento webpack necesita la instalación de **2 dependencias de desarrollo**:
* **webpack**
* **webpack-cli**

```js
npm i webpack webpack-cli -D
```
> *Con este comando puedes instalar ambas dependencias en una sola línea*
> ** La bandera `-D` hace que ambas dependencias se instalen como dependencias de desarrollo.
> *Es importante tener un `package.json` antes de hacer las instalaciones, pero que este punto es más que obvio mencionarlo.*

## **`webpack.config.js`**<a name="id6"><a/>
Es un archivo especial de configuración que tiene webpack donde podemos anotar explícitamente todas las reglas de empaquetado con las cuales funcionará el proyecto; no es más que un objeto javascript donde con propiedades clave-valor configuramos la app correspondiente.
> *Este archivo por lo general se lo crea en la raíz del proyecto*

## **Puntos clave de webpack**<a name="id7"><a/>
Para entender webpack en necesario comprender 5 puntos fundamentales:
### **Entry**
`Entry` es el punto de entrada de nuestra app, en otras palabras, indica el archivo principal el cual arranca la app.
Por defecto, webpack toma la ruta `./src/index.js` como archivo de entrada, pero puedes configurar cualquier otra ruta relativa que quieras.

```js
//webpack.config.js
module.exports = {
  entry: './path/to/my/entry/file.js',
};

```
> *Nota como usamos sintaxis de Common.js (`module.exports`) para envolver todas las configuraciones.*

### **Output**
`Output` es el punto de salida de la app, que indica a webpack en donde guardará los archivos listos para producción, como ser archivos `.js`, `.html` y `.css`
Por defecto estos archivos se almacenan en la ruta `./dist/main.js` pero es posible especificar cualquier otra **ruta absoluta**.
En el archivo de configuración se veria asi:

```js
//webpack.config.js
const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js',
  },
};
```
Donde:
> `path` indica la ruta absoluta donde se guardarán los archivos resultantes. Nótese que se usa la constante `__dirname` de node para escribir la ruta
> `filename` indica el nombre del archivo javascript resultante.

### **Loaders**
Por defecto webpack solo trabaja con archivos `.js` y `.json`, pero todos sabemos que todas las webs tienen HTML Y CSS, entonces, ¿cómo solucionamos esto? La respuesta son los **Loaders**

Los loaders permiten a webpack procesar otros tipos de archivos para que lo convierta en módulos válidos para producción.

De manera muy genérica, un loader está compuesto de 2 partes principales:
* `test`: identifica qué tipos de archivos deben transformarse, por lo general es una expresión regular
* `use`: indica el loader propiamente dicho que se debe usar para realizar la transformación antes mencionada.

Veamos un ejemplo en nuestro archivo de configuración:

```js
//webpack.config.js
const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js',
  },
  module: {
     rules: [
         {
            test: /\.css$/i,
            use: ["style-loader", "css-loader"],
         },
     ],
  },
};
```
**Aspectos importantes a considerar:**
* Observa como los loaders se cargan en un objeto `module` que tienen un arreglo `rules`.
* La expresión regular `test: /\.txt$/` debe estar sin comillas simples ni dobles.
* La regla del ejemplo dice más o menos esto: *webpack, se que no comprendes archivos `.css`, por ello te paso un loader llamado `style-loader` y otro llamado `css-loader` para que los uses en todos los archivos `.css` del proyecto.*
* El orden de los loaders es importante.
* Para que la configuración funciones satisfactoriamente se debe respetar el orden de las reglas, primero debe ir el `test` y luego el `use`.

### **Plugins**
Quizá el concepto más sencillo de entender por que su propio nombre es bastante descriptivo.
Básicamente los `plugins` se encargan de extender características que por defecto webpack no tiene, como la optimización de paquetes, la administración de archivos, por ejemplo, HTML Y CSS, y el manejo de variables de entorno.

Veamos nuestro archivo de configuración usando plugins:

```js
//webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //dependencia instalada via npm
const webpack = require('webpack'); //acceso a los 23 plugins que webpack trae por defecto

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js',
  },
  module: {
      rules: [
          {
             test: /\.css$/i,
             use: ["style-loader", "css-loader"],
          },
      ],
  },
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};

```
Puntos a considerar:
* Para este ejemplo primeramente se debe instalar e importar el plugin `html-webpack-plugin` desde `npm` haciendo: `npm i html-webpack-plugin`
* Los plugins para ser usados necesitan una instancia, por ello hacemos `new HtmlWebpackPlugin()` y le pasamos la propiedad `template` y le indicamos la ruta de nuestro `index.html`
* Como webpack no permite por defecto la salida de archivos `.html` necesitamos este plugin.

> *Webpack hasta su versión 5 cuenta con 23 plugins que vienen preinstalados listos para ser usados, puedes verlos en su [documentacion oficial](https://webpack.js.org/plugins/)*

### **Mode**
Le indica a webpack en qué modo se desea empaquetar el código.
Puede ser en modo `production`:
```js
module.exports = {
  mode: 'production',
};
```
Donde todos nuestros archivos de salida estarán minificados.
O puede ser en modo `development`:
```js
module.exports = {
  mode: 'development',
};
```
Donde todos nuestros archivos de salida no están minificados.

Un tipo y básico archivo de configuración de webpack se podrá ver de la siguiente manera:

```js
//webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //dependencia instalada via npm

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js',
  },
  mode: 'production',
  module: {
      rules: [
         {
            test: /\.css$/i,
            use: ["style-loader", "css-loader"],
         },
     ],
  },
  // más reglas...
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
  // más plugins...
};

```
> Con este código de configuración ya se tiene lo básico para poder manipular archivos `.html`, `.css` y `.js` en un proyecto.
> Esta configuración será útil más adelante para por ejemplo poder implementar react en el proyecto.

## **Referencias**<a name="id8"><a/>
* [Documentación oficial](https://webpack.js.org/)
* Webpack 4, Curso Práctico | Fazt
{% youtube vF2emKbaP4M %}
* Aprende webpack paso a paso | Midudev
{% youtube ansUGkcrhwY %}


## **Conclusiones**<a name="id9"><a/>
* Webpack es un empaquetador de módulos para frontend, posiblemente el más popular.
* Para usar webpack necesitas instalar 2 dependencias: `webpack` y `webpack-cli`
* Las configuraciones de webpack se deben hacer en un archivo `webpack.config.js` que se crea en la raíz del proyecto.
* Webpack tiene 5 puntos fundamentales: `entry`, `output`, `loaders`, `plugins` y `mode`.
* Aprender webpack básico es bastante sencillo, pero a medida que tu proyecto crece y se hace más complejo webpack también necesitará configuraciones más complejas. Este post es solo introductorio.

---

Posiblemente los siguientes artículos sean de tu interés: 

{% link https://dev.to/duxtech/es6-promesas-en-javascript-5bpb %}

{% link https://dev.to/duxtech/como-rayos-funciona-el-hook-useref-en-react-2lah %}

{% link https://dev.to/duxtech/local-storage-api-en-javascript-o88 %}

![img](https://media.giphy.com/media/KINAUcarXNxWE/giphy.gif)