O webpack é um empacotador de módulos estáticos moderno para projetos JavaScript. Ele analisa a aplicação para cnostruir um grafo de dependências, incluindo todos os módulos necessários, e os empacota em um ou mais bundles.
Instalação e Configuração Básica
Antes de começar, certifique-se de ter o Node.js instalado na versão mais recente.
- Instalação global (opcional):
npm install webpack webpack-cli -g - Instalação local (recomendado):
npm install webpack webpack-cli --save-dev
Para executar o webpack, utilize o comando npx webpack, que invoca a versão instalada localmente. A partir da versão 4.0, o webpack permite builds com configuração mínima, mas para projetos reais, é comum usar um arquivo de configuração.
Conceitos Fundamentais
- Entrada (entry): O arquivo principal de JavaScript.
- Saída (output): O local e nome do bundle gerado.
- Carregadores (loaders): Transformam módulos antes do empacotamento.
- Plugins (plugins): Realizam tarefas adicionais durante o build.
Crie um arquivo webpack.config.js na raiz do projeto com a seguinte estrutura:
const caminho = require('path');
module.exports = {
// Ponto de entrada da aplicação
entry: './src/aplicacao.js',
// Configuração da saída
output: {
path: caminho.resolve(__dirname, 'saida'),
filename: 'pacote-principal.js'
},
// Modo de desenvolvimento para facilitar a depuração
mode: 'development'
};
Adicione um script no package.json para simplificar a execução:
{
"scripts": {
"build": "webpack"
}
}
Execute com npm run build.
Ferramentas de Desenvolvimento Automatizado
Modo de Observação (Watch)
Para monitorar alterações nos arquivos e recompilar automaticamente, use o flag --watch:
"scripts": {
"watch": "webpack --watch"
}
Execute com npm run watch. Alternativamente, configure no webpack.config.js:
module.exports = {
// ... outras configurações
watch: true
};
Servidor de Desenvolvimento (devServer)
O webpack-dev-server fornece um serviodr com hot reloading.
- Instale as dependências:
npm install webpack-dev-server webpack --save-dev - Configure o script:
"dev": "webpack-dev-server --hot --open --port 3001"
Para personalizar, adicione no webpack.config.js:
module.exports = {
// ... configurações anteriores
devServer: {
port: 3001,
open: true,
hot: true
}
};
Middleware de Desenvolvimento
Para controle mais granular, use webpack-dev-middleware com Express:
const express = require('express');
const webpack = require('webpack');
const middleware = require('webpack-dev-middleware');
const configuracao = require('./webpack.config.js');
const app = express();
const compilador = webpack(configuracao);
app.use(middleware(compilador, {
publicPath: '/'
}));
app.listen(3000, () => {
console.log('Servidor rodando em http://localhost:3000');
});
Processando Diferentes Tipos de Recursos
CSS e Pré-processadores
Para integrar CSS, instale os carregadores:
npm install css-loader style-loader --save-dev
Configuração no webpack.config.js:
module.exports = { module: { rules: [ { test: /.css$/, use: ['style-loader', 'css-loader'] } ] } };
<p>Para Less ou Sass, adicione carregadores específicos como <code>less-loader</code> ou <code>sass-loader</code>.</p>
<h3>Imagens e Fontes</h3>
<p>Utilize <code>file-loader</code> ou <code>url-loader</code> para otimizar recursos gráficos:</p>
<code>module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: {
limit: 8192, // 8KB
outputPath: 'assets',
name: '[name]-[hash:5].[ext]'
}
}]
}
]
}
};</code>
<h3>Transpilação com Babel</h3>
<p>Para suportar ES6+ no navegador:</p>
- Instale dependências:
npm install babel-loader @babel/core @babel/preset-env --save-dev - Para recursos avançados, adicione plugins como
@babel/plugin-proposal-class-properties.
Configuração:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/env']
}
}
}
]
}
};
Para usar generators ou métodos de protótipo ES6+, configure o .babelrc com @babel/plugin-transform-runtime e @babel/polyfill.
Mapas de Código-Fonte (Source Maps)
A opção devtool controla a geração de source maps para depuração. Para ambientes de desenvolvimento, recomenda-se cheap-module-eval-source-map por oferecer bom desempenho e mapeamento correto. Em produção, evite source maps para segurança e desempenho.
Plugins Essenciais
Limpeza de Diretórios
Use clean-webpack-plugin para limpar a pasta de saída antes de cada build:
const LimparPlugin = require('clean-webpack-plugin');
module.exports = {
plugins: [
new LimparPlugin()
]
};
Cópia de Arquivos
O plugin copy-webpack-plugin copia arquivos estáticos:
const CopiarPlugin = require('copy-webpack-plugin');
module.exports = {
plugins: [
new CopiarPlugin([
{
from: caminho.join(__dirname, 'recursos'),
to: 'recursos'
}
])
]
};
Configurações Avançadas
Imagens em HTML
Para processar imagens em tags img, use html-withimg-loader:
module.exports = {
module: {
rules: [
{
test: /\.(html|htm)$/,
loader: 'html-withimg-loader'
}
]
}
};
Aplicações de Múltiplas Páginas
Configure múltiplos pontos de entrada e use instâncias do html-webpack-plugin para cada página:
const GerarHTML = require('html-webpack-plugin');
module.exports = {
entry: {
principal: './src/principal.js',
secundario: './src/secundario.js'
},
output: {
filename: '[name].js'
},
plugins: [
new GerarHTML({
template: './index.html',
filename: 'index.html',
chunks: ['principal']
}),
new GerarHTML({
template: './index.html',
filename: 'secundario.html',
chunks: ['secundario']
})
]
};
Injeção de Bibliotecas Globais
Para bibliotecas como jQuery, use expose-loader ou o plugin ProvidePlugin:
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
};
Configurações por Ambiente
Divida as configurações em arquivos base, desenvolvimento e produção, usando webpack-merge para combinar:
// webpack.config.producao.js
const base = require('./webpack.config.base.js');
const { merge } = require('webpack-merge');
module.exports = merge(base, {
mode: 'production'
});
Variáveis de Ambiente
Defina variáveis com DefinePlugin para alternar entre ambientes:
module.exports = {
plugins: [
new webpack.DefinePlugin({
AMBIENTE: JSON.stringify('producao')
})
]
};
Proxy para Resolução de CORS
Configure o devServer para redirecionar requisições:
module.exports = {
devServer: {
proxy: {
'/api': 'http://localhost:4000'
}
}
};
Hot Module Replacement (HMR)
Ative o HMR para atualização de módulos em tempo real:
if (module.hot) {
module.hot.accept('./modulo-quente.js', () => {
console.log('Módulo atualizado');
const novoModulo = require('./modulo-quente.js');
// Lógica adicional
});
}