Configurar Webpack & React Parte 6 - 🌄 Soporte de estilos e imágenes.
Tags: javascript, react, webpack, webdev
Published: 2020-07-07 03:06:00

En esta entrega vamos a instalar los paquetes necesarios para que webpack sepa como tratar estilos e imágenes en nuestro proyecto de react.

## Estilos

Nos disponemos a instalar los paquetes necesarios:

```bash
npm install --save-dev mini-css-extract-plugin css-loader node-sass sass-loader
```

#### [node-sass](https://github.com/sass/node-sass)
Esta librería transforma sass o scss a css, es usada por `sass-loader`.

#### [sass-loader](https://webpack.js.org/loaders/sass-loader/)
Nos ayuda a cargar los archivos sass o scss y convertirlos a css, internamente usa `node-sass` para ello.

#### [css-loader](https://webpack.js.org/loaders/css-loader/)
Nos ayuda a resolver las importaciones del tipo `import css from 'file.css';` que declaremos en nuestra aplicación de react.

#### [mini-css-extract-plugin](https://webpack.js.org/plugins/mini-css-extract-plugin/)
Nos ayuda a guardar en disco los archivos css que fueron el resultado de ser tratados con los plugins descritos anteriormente.

### Agregando el soporte de estilos a Webpack

Como paso siguiente debemos editar nuestro `webpack.config.js` para configurar los plugins

#### Añadiendo la nueva regla a webpack.config.js

Tenemos que añadir una nueva regla para que webpack pueda reconocer y transformar los archivos `scss`, `css`.

```javascript
{
  test: /\.(s*)css$/,
  use: [
    { loader: MiniCssExtractPlugin.loader },
    "css-loader",
    "sass-loader",
  ],
},
```

#### Importando mini-css-extract-plugin

En la parte superior igual indicaremos que vamos a requerir `mini-css-extract-plugin`

```javascript
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
```

#### Usando mini-css-extract-plugin

En la sección de scripts debemos agregar el uso de este nuevo plugin para poder exportar los css previamente convertidos.

```javascript
  plugins: [
    ...
    new MiniCssExtractPlugin({
      filename: "assets/[name].css",
    }),
  ],
```

#### Todo junto

Teniendo como resultado el siguiente:

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

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  resolve: {
    extensions: [".js", ".jsx"],
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: "html-loader",
          },
        ],
      },
      {
        test: /\.(s*)css$/,
        use: [
          { loader: MiniCssExtractPlugin.loader },
          "css-loader",
          "sass-loader",
        ],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
      filename: "index.html",
    }),
    new MiniCssExtractPlugin({
      filename: "assets/[name].css",
    }),
  ],
};

``` 

### Agregando un estilo

Dentro de `src` debemos crear un carpeta nueva llamada `assets` y dentro de esta una llamada `styles`. Seguido debemos crear un archivo llamado `Main.scss`.

Deberemos tener un árbol de archivos y directorios como el siguiente.

```bash
.
├── dist
│   ├── bundle.js
│   └── index.html
├── public
│   └── index.html
├── src
│   ├── assets
│   │   └── styles
│   │       └── Main.scss
│   ├── components
│   │   └── HolaMundo.jsx
│   └── index.js
├── .babelrc
├── package-lock.json
├── package.json
└── webpack.config.js
```

#### Main.scss

Solo debemos colocarle el siguiente contenido de prueba.

```sass
$background-color: #282c34;
$text-color: #fff;

* {
  margin: 0;
  padding: 0;
}
.container {
  background-color: $background-color;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: $text-color;
}
```

#### Importando Main.scss

Lo que debemos hacer es importar nuestros estilos en nuestro componente `HolaMundo.jsx` y hacerle una actualización para que tenga un `div` contenedor.

```jsx
import React from "react";
import "../assets/styles/Main.scss";

const HolaMundo = () => {
  return (
    <div className="container">
      <h1>Hola mundo</h1>
    </div>
  );
};

export default HolaMundo;
```

#### Probando los estilos.

Como ultimo paso de esta sección solo debemos correr nuestro proyecto y ver si todo marcha bien.

```bash
npm run start
```

![Hola Mundo](https://dev-to-uploads.s3.amazonaws.com/i/vz7yzp5lpu0mc6g8wc3g.png)

## Imágenes

En el caso de las imágenes el procedimiento es un poco mas sencillo, lo primero es añadir el plugin `file-loader` de webpack.

```bash
npm install --save-dev file-loader
```

#### [file-loader](https://webpack.js.org/loaders/file-loader/)
Resuelve las importaciones de archivos y nos permite guardarlos, en este caso lo usaremos para que resuelva las imágenes.

### Agregando el soporte de imágenes a Webpack

Como paso siguiente debemos editar nuestro `webpack.config.js` para configurar el loader.

#### Añadiendo la nueva regla

Tenemos que añadir una nueva regla para que webpack pueda reconocer los archivos `png`, `jpe`, `jpeg`, `gif` e indicarle donde debe guardarlos

```javascript
{
  test: /\.(png|jpe?g|gif)$/i,
  use: [
    {
      loader: 'file-loader',
      options: { name: 'assets/[hash].[ext]' },
    },
  ],
},
```

Teniendo como resultado lo siguiente.

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

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  resolve: {
    extensions: [".js", ".jsx"],
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: "html-loader",
          },
        ],
      },
      {
        test: /\.(s*)css$/,
        use: [
          { loader: MiniCssExtractPlugin.loader },
          "css-loader",
          "sass-loader",
        ],
      },
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: "file-loader",
            options: { name: "assets/[hash].[ext]" },
          },
        ],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
      filename: "index.html",
    }),
    new MiniCssExtractPlugin({
      filename: "assets/[name].css",
    }),
  ],
};

```

### Agregando una imagen

Ahora dentro de la carpeta `assets` debemos crear una carpeta llamada `static` en donde guardaremos nuestra imagen, en mi caso busque una de react en [iconfinder](https://www.iconfinder.com/) y la guarde con el nombre de `react.png`.

Obtenemos un árbol de archivos y directorios como el siguiente.

```bash
.
├── dist
│   ├── bundle.js
│   └── index.html
├── public
│   └── index.html
├── src
│   ├── assets
│   │   ├── static
│   │   │   └── react.png
│   │   └── styles
│   │       └── Main.scss
│   ├── components
│   │   └── HolaMundo.jsx
│   └── index.js
├── .babelrc
├── package-lock.json
├── package.json
└── webpack.config.js
```

#### Importando la imagen.

A continuación debemos modificar de nuevo nuestro componente `HolaMundo.jsx` para importar la imagen, después agregar una etiqueta `img` para poder visualizarla.

```jsx
import React from "react";
import "../assets/styles/Main.scss";
import reactImg from "../assets/static/react.png";

const HolaMundo = () => {
  return (
    <div className="container">
      <img src={reactImg} alt="imagen de react" />
      <h1>Hola mundo</h1>
    </div>
  );
};

export default HolaMundo;
```

#### Probando la importación de imágenes

Ahora solo debemos correr de nuevo el servidor de desarrollo.

```bash
npm run start
```
![React e imagenes](https://dev-to-uploads.s3.amazonaws.com/i/4lj8ajkhb3swsg59nt5b.png)

## Despedida

Ahora ya tenemos soporte de estilos e imágenes, en la siguiente entrega daremos soporte de ESLint para tener mejores practicas de programación.