Implementando Webpack em um projeto MVC com JavaScript
Tags: webpack, javascript, mvc, github
Published: 2022-03-23 15:53:30

Imagine um cenário em que um site só é feito em **HTML, CSS e JavaScript (JS)**, esse site começa a tomar proporções maiores do que imaginávamos, o arquivo JS que contém as funcionalidades começa a ficar gigantesco, começamos a criar arquivos JS para dividir cada funcionalidade, importamos cada script em uma ordem muito especifica no HTML. 

Mas isso vai ficando enorme e cada deslize o site quebra, você pode ver que esse cenário pode ir de mal a pior e com isso ficando impossível de trabalhar.

Neste artigo, vamos falar como **webpack** pode melhorar nosso desenvolvimento e como ele é aplicado em um pequeno projeto que construí nesse [post](https://www.isarubim.com/posts/construindo-um-simples-projeto-mvc-do-zero-com-javascript) explicando a arquitetura Model View Controller (MVC).

![Projeto consumindo API do GitHub feito com arquitetura MVC](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dve4w7s8rkuwhc7mch6j.png)

Você pode clonar diretamente do GitHub já estruturado para iniciar a configuração do webpack.

## O que é webpack?

Webpack nada mais é do que um empacotador de módulos, ele serve para que não tenhamos arquivos gigantescos e que podemos dividir eles tranquilamente sem ter necessariamente uma ordem especifica como comentei, ao invés disso podemos importar cada um em seu respectivo lugar que será usado. E tudo isso é compactado em uma pasta **dist** que é usada para quando o projeto estiver no ar 🎉

## O que vai ter nesse projeto com Webpack configurado? 

Esse projeto vai conter arquivos de configuração Babel que é um tradutor para JS mais moderno que traduz para um JS mais antigo que é suportado em vários navegadores, assim não precisamos nos preocupar em usar os recursos mais modernos do JS, além disso usando a arquitetura MVC. Muito bom, né? Sem mais delongas vamos sujar nossas mãos e configurar nosso projeto.

## Criando um arquivo webpack.config.js

Na raiz do projeto, vamos criar um arquivo chamado **webpack.config.js** nele será configurado tudo que precisamos para ter o webpack no nosso projeto. Após criar o arquivo, vamos instalar o webpack. Em seu terminal digite o seguinte comando:

```shell
npm install webpack webpack-cli webpack-dev-server --save-dev
```

No comando contém 3 pacotes:

- **webpack**: instalará o webpack de fato;
- **webpack-cli**: fornece vários comandos para que podemos configurar o webpack personalizado;
- **webpack-dev-server**: isso nos ajudará no desenvolvimento, podendo assistir nossas mudanças no código com recarregamento automático.

Voltando no arquivo webpack.config.js, vamos colar o seguinte código:

```js
const path = require("path");

module.exports = {
  entry: "./src/js/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/bundle.js",
  },
  devServer: {
    static: {
      directory: path.join(__dirname, "src"),
    },
    compress: true,
    port: 9000,
  },
  },
};
```

Para entendermos o que está acontecendo aqui, primeiramente:

A propriedade **entry** é o ponto que define onde o projeto iniciará e está recebendo o arquivo principal **index.js** que é o nosso Controller da arquitetura MVC. 

Já o **output** é onde definimos como será nossa saída depois do agrupamento dos arquivos, aqui estamos dizendo a propriedade path do objeto output para que crie uma pasta **dist** que terá um arquivo **bundle** dentro da pasta js que está sendo definido no filename.

E o **devServer** que nada mais é onde definimos a pasta em que o webpack fica olhando as mudanças que ocorre no desenvolvimento e reflete em nosso navegador fazendo o recarregamento após salvar o arquivo.

## Configurando o Babel

Inicialmente, precisamos instalar o babel e alguns pacotes relacionados, em seu terminal digite:
    
```shell
npm install @babel/core @babel/preset-env --save-dev
```

- **@babel/core**: é onde contém as funcionalidades principais de todo o babel;
- **@babel/preset-env**: contém vários plugins que ajuda a traduzir nosso JS.

E em seguida precisamos instalar o **polyfill** do babel que irá ligar o babel com o webpack, no terminal digite:

```shell
npm install @babel/polyfill --save
```

Após instalar os pacotes, na raiz do projeto vamos criar um arquivo chamado **.babelrc** nele irá conter nossas configurações para traduzir o JS moderno para o mais antigo, no arquivo coloque:

```json
{
  "presets": [
      ["@babel/preset-env", {
          "targets": {
            /* 
            * Suporta as últimas 5 versões de cada navegador e certifica de que 
            * todas as versões do IE (a partir da 8) sejam compatíveis.
            */
            "browsers": [
                "last 5 versions",
                "ie >= 8"
            ]
          }
      }]
  ]
}
```

A propriedade **targets** que contém a propriedade browsers diz para suportar as últimas 5 versões de cada navegador e certifica de que todas as versões a partir da 8 do Internet Explorer sejam compatíveis.

Agora vamos até o arquivo **webpack.config.js** que criamos e vamos acrescentar o **polyfill** do babel no na propriedade entry, ficando assim nosso arquivo:

```js
const path = require("path");

module.exports = {
  entry: ["@babel/polyfill", "./src/js/index.js"],
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/bundle.js",
  },
  devServer: {
    static: {
      directory: path.join(__dirname, "src"),
    },
    compress: true,
    port: 9000,
  },
};
```

## Instalando plugins

Os plugins no webpack é um facilitador para otimizar o nosso desenvolvimento em determinadas tarefas.

O primeiro que vamos instalar é o **html-webpack-plugin** que faz com que nosso HTML esteja na pasta de saída com os pacotes e com os arquivos usados já importados como o **index.js** no nosso arquivo HTML.

Em seu terminal, digite:

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

Em seguida, vamos instalar um plugin muito útil também que se chama **mini-css-extract-plugin** em conjunto com o **css-loader**:

```shell
npm install mini-css-extract-plugin css-loader --save-dev
```

- **mini-css-extract-plugin**: separa os arquivos CSS por arquivo JS que contém CSS;
- **css-loader**: usado para interpretar import, url(), require() em arquivos JS.

Agora vamos adicionar nossos plugins no nosso arquivo webpack.config.js:

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

module.exports = {
	/*...*/
	plugins: [
		new HtmlWebpackPlugin({
		  filename: "index.html", // Arquivo de saída em nossa pasta dist
		  template: path.resolve(__dirname, "./src/index.html"), // Nosso arquivo HTML do projeto
		}),
		new MiniCssExtractPlugin({
		  filename: "css/[name].css", // Arquivo de saída em nossa pasta dist
		}),
	],
	module: {
		rules: [
		  {
			test: /\.css$/i,
			use: [MiniCssExtractPlugin.loader, "css-loader"],
		  },
		],
	},
}
```
E no **index.js** importamos o nosso arquivo css:

```js
import "../css/styles.css";
```

## Scripts

No package.json, adicione os scripts:

```json
 "scripts": {
    "build": "webpack --mode production", // Gera a pasta dist
    "start": "webpack-dev-server --mode development --open" // Inicia a aplicação para o desenvolvimento
  },
```

Agora vamos rodar um comando para gerar a pasta dist:

```shell
npm run build
```  

E em seguida o comando para rodar nossa aplicação e abrir ela no navegador pelo endereço **http://localhost:9000/**:

```shell
npm start
``` 

Podemos ver a pasta **dist** que contém um HTML empacotado, pasta css com nosso arquivo main.css e a pasta js com nosso arquivo bundle.js apenas com recursos do JS suportados para os browsers que definimos no arquivo de configuração babel.

## Conclusão

Criamos um arquivo de configuração para o webpack 5 simples, pronto para seu uso em produção, com Babel, MVC, otimização em produção e um servidor de desenvolvimento. Webpack tem muitas outras funcionalidades, mas esse artigo pode ser um começo, mas recomendo entrar em mais detalhes, um exemplo é como você pode implementar o SASS em seu projeto em conjunto com a configuração que utilizamos nesse post. Com isso, você tem uma bagagem para criar outras aplicações com Framework ou o que preferir 🤯😄

- [Ver demonstração](https://mvc-webpack.netlify.app/)
- [Ver código fonte](https://github.com/IsabelRubim/mvc-webpack)

Agora divirta-se, qualquer dúvida, pode enviar no meu [twitter](https://twitter.com/belrubim) que estarei por lá 🤗