Webpack – Aprendendo um pouco sobre.

Afinal de contas, o que é Webpack?

Fala galera, beleza? O que acha de entendermos juntos o que é Webpack?

Neste artigo vou falar um pouco sobre o que é o tão falado, tentarei ser o mais claro e sucinto possível (assim espero 😬).

O código deste post pode ser encontrado no meu github

Webpack é um empacotador de módulos de aplicações javascript. What? Calma, eu explico!

O que é?

Na versão 5 do ESCMAScript tinhamos o conceito de module pattern, porém a linguagem não oferecia isso de forma nativa, precisávamos fazer um work around, a famosa gambiarrinha. A versão 2015 da linguagem trouxe esse conceito de forma nativa com a palavra reservada module, o que nos possibilita dividir nossa aplicação em dezenas de partes, e o que ganhamos com isso? Manutenabilidade, melhor controle no escopo das variáveis, facilita seguir o DRY, entre outras vantagens. Porém, isso nos traz um problema de controle, imagine você ter dezenas de componentes (arquivos js) e precisar incluir isso em seu html e se preocupar com a ordem que isso será incluído para não ter problema de chamar um módulo e ele ainda não ter sido carregado. É exatamente este problema que o Webpack nos ajuda a resolver.

O que funciona melhor que palavras? Isso mesmo, ibagens, então vamos dar uma ilustrada no assunto.

Conceito do webpack
Imagem retirada do site oficial do projeto.

Vamos entender o que esse labirinto de setinhas quer dizer.

Em resumo o que o Webpack faz é pegar todos os módulos e suas dependências e gerar uma build de tudo, nas ordens corretas, você não precisa se preocupar com nada, pois, o garotão ai fará todo o trabalho duro e você terá apenas que incluir essa build em seu arquivo html. Vamos ver isso na pática

Configurando

Criando o projeto

mkdir conceito_webpack
cd conceito_webpack

Agora vamos inicializar o criar o package.json e já responder a todas as perguntas que o terminal básicas do projeto nos faz com a flag -y

npm init -y

O terminal nos mostrará o json criado como saída do comando acima

{
  "name": "conceito_webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Agora vamos instalar o Webpack

npm i webpack webpack-dev-server --save-dev

Instalamos também o servidor de desenvolvimento do webpack e utilizamos a flag –save-dev para salvarmos a dependência em nosso package.json apenas em ambiente de desenvolvimento.

Se tudo correu bem, nosso package.json foi atualizado

{
  "name": "conceito_webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^2.4.1",
    "webpack-dev-server": "^2.4.5"
  }
}

Agora precisamos criar o arquivo de configuração do webpack chamado webpack.config.js

touch webpack.config.js

Vamos utilizar uma configuração inicial bem básica, descreverei com comentários no próprio código o que cada linha faz.

/**
 * require() é uma função node, por isso, preciso apenas fornecer o nome do pacote
 * e ele sabe que deve buscar o arquivo node_modules/webpack/bin/webpack.js 
 * e criar a referência.
 */
const webpack = require('webpack')

module.exports = {
  /**
   * Para o webpack gerar o build de sua aplicação, ele precisa saber 
   * qual será o ponto de entrada, o arquivo raiz, que chamará em forma de árvore
   * todos os módulos subjacentes.
   */
  entry: './app/index.js',
  /**
   * Precisamos dizer ao webpack também, qual será o local de saída de nosso build
   */
  output: {
    /**
     * no nosso caso utilizamos a variável de ambiente do node '__dirname' que 
     * pega nosso diretório atual e concatenamos com a pasta public
     */
    path: __dirname + '/public',
    /**
     * Dizemos também qual o nome do nosso arquivo, por convenção utilizaremos
     * o nome 'bundle.js', mas você é livre pra coloar o nome que quiser.
     */
    filename: './bundle.js'
  },
  /**
   * Aqui setamos qual o servidor de dev que utilizaremos, lembra que instalamos
   * o webpack-dev-server agorinha?
   */
  devServer: {
    // Eu escolhi a 3000, mas você pode escolher a que se sentir mais confortável.
    port: 3000,
    // Aqui dizemos onde estará nosso arquivo bundle.js
    contentBase: './public'
  }
}

Agora precisamos criar as pastas e arquivos que colocamos em nossa configuração

mkdir app
touch app/index.js
mkdir public
touch public/index.html

Nosso arquivo public/index.html terá uma estrutura bem básica e chamará o nosso bunde.js, repare que estamos dentro do mesmo diretório, logo, não precisamos do public antes da chamada do arquivo

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Conceito Webpack</title>
</head>
<body>
  <script src="bundle.js"></script>
</body>
</html>

Vamos criar 2 arquivos (módulos) dentro da pasta app
author.js

exports.name = (name) => name;

book.js

const author = require('./author')
exports.info = (title, author) => `Título: ${title}, escrito por: ${author}`

Repare que estou referenciando author.js através da função node require()

index.js
Também referenciarei dentro de index.js o arquivo book.js e damos um
console.log
pra ver o resultado

const book = require('./book')
console.log(book.info('Spider-Man', 'Stan Lee'))

Precisamos configurar um script que rode o servidor e habilite o hot reload, para isso edite o arquivo package.json com o seguinte código.

"scripts": {
  "dev": "webpack-dev-server --progress --colors --inline --hot"
},

Agora basta rodarmos o comando

npm run dev

que teremos um servidor que após cada alteração que fizermos, irá atualizar automaticamente.
Note que o arquivo bundle.js não foi gerado fisicamente em seu diretório public, isso acontece, pois, o webpack-dev-server gera uma cópia em memória e a referencia. Para gerar o arquivo físico, você precisa rodar o seguinte comando

 

./node_modules/.bin/webpack

Caso tenha o webpack instalado globalmente, basta rodar apenas

webpack

Obs: Quando qualquer alteração for feita no arquivo webpack.config.js o servidor deverá ser parado e startado novamente.

Conclusão

Após toda a configuração que fizemos ao longo deste post, a partir de agora, poderemos focar 100% no desenvolvimento de novos módulos, sem nos preocuparmos como isso será carregado na aplicação, qual ordem, etc., o Webpack cuida disso daqui pra frente.
Utilizar o Webpack não é tão complexo quanto pensamos, demanda um pouco de paciência para configurar e se adaptar à algumas coisas, porém, é uma mão na roda.

Em um próximo post abordarei o Babel, um transpilador de javascript.

Até a próxima. 👾