Configurando o Webpack 5 do zero





Aprenda a usar o webpack para construir JavaScript, imagens, fontes e estilos, e como executar o



servidor de desenvolvimento. Se você já usou o webpack 4 antes, aqui estão algumas das diferenças da versão 5:



  • o comando "webpack-dev-server" agora se parece com "webpack-serve"
  • a instalação separada de file-loader, raw-loader e url-loader não é mais necessária, você pode usar os módulos de ativos integrados
  • Node.js , , , stream, «stream-browserify» { stream: «stream-browserify» }


?



Na maioria das vezes, os sites não são mais escritos em HTML puro com pouco JavaScript - frequentemente, eles são criados apenas com JavaScript. Portanto, torna-se necessário construir, minificar e transpilar o código. É aqui que o webpack é útil.



Webpack é um construtor de módulo. Ele é usado para empacotar o código para uso pelo navegador. Ele permite que você aproveite os recursos mais recentes do JavaScript com o Babel ou use o TypeScript e o compile para um código minimizado para navegadores diferentes. Ele também permite que você importe recursos estáticos para o JavaScript.



Para desenvolvedores, o webpack também oferece um servidor de desenvolvimento que pode atualizar módulos e estilos instantaneamente quando o arquivo é salvo. Ferramentas de linha de comando como "vue create" e "react-create-app" usam o webpack nos bastidores, mas você pode criar facilmente sua própria configuração de webpack para essas estruturas.



O Webpack também pode fazer muitas outras coisas, mas este artigo cobrirá os princípios básicos de configuração e uso.



Instalação



Crie um diretório de projeto e inicialize-o:



mkdir webpack-tutorial
cd !$
// 
cd webpack-tutorial
yarn init -yp  //     "package.json"
// 
npm init -y


Instale webpack e webpack-cli como dependências de desenvolvimento:



yarn add -D webpack webpack-cli
// 
npm i -D webpack webpack-cli




Crie um diretório "src" para armazenar os arquivos do aplicativo. Vou começar criando um arquivo "index.js" simples:



console.log(" !")


Ótimo, temos um projeto Node.js com os pacotes principais instalados e um arquivo "index.js". Vamos começar a configurar o webpack.



Configuração básica



Vamos começar a configurar o coletor. Crie um arquivo "webpack.config.js" no diretório raiz do projeto.



Ponto de entrada


Em primeiro lugar, você precisa definir o ponto de entrada do aplicativo, ou seja, quais arquivos o webpack irá compilar. No exemplo acima, definimos o ponto de entrada como "src / index.js":



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

module.exports = {
    entry: {
        main: path.resolve(__dirname, './src/index.js'),
    },
}


Ponto de saída


O ponto de saída é o diretório onde os arquivos compilados pelo webpack são colocados. Defina o ponto de saída para "dist". O prefixo "[nome]" corresponde ao nome do arquivo em src:



// webpack.config.js
module.exports = {
    // ...

    output: {
        path: path.resolve(__dirname, './dist'),
        filename: '[name].bundle.js',
    },
}


A configuração mínima para construir o projeto está pronta. Adicione o script "build" ao arquivo "package.json" que executa o comando "webpack":



// package.json
"scripts": {
    "build": "webpack"
}


Inicie o pacote da web:



yarn build
// 
npm run build


asset main.bundle.js 19 bytes [emitted] [minimized] (name: main)
./src/index.js 18 bytes [built] [code generated]
webpack 5.1.0 compiled successfully in 152 mss


O arquivo “index.bundle.js” é criado no diretório “dist”. O arquivo não mudou, mas construímos o projeto com sucesso.



Plugins



A interface do plugin torna o webpack muito flexível. Os plug-ins são usados ​​pelo próprio webpack e por extensões de terceiros. Alguns plug-ins são usados ​​em quase todos os projetos.



Plugin baseado em modelo HTML


Temos um assembly pronto, mas é inútil sem marcação, que carregará o assembly como um script. Como queremos que esse arquivo HTML seja gerado automaticamente, usamos o plug-in html-webpack.





Instale o plugin:



yarn add -D html-webpack-plugin


Crie um arquivo "template.html" no diretório "src". Podemos adicionar variáveis ​​e outras informações ao modelo. Adicione a variável "title", caso contrário, o modelo se parecerá com um arquivo HTML normal com um contêiner com o identificador "root":



<!-- src/template.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>

  <body>
    <div id="root"></div>
  </body>
</html>


Adicione a propriedade "plugins" às configurações do webpack, onde definimos o plugin, o nome do arquivo de saída (index.html) e o template:



// webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    // ...

    plugins: [
        new HtmlWebpackPlugin({
            title: 'webpack Boilerplate',
            template: path.resolve(__dirname, './src/template.html'), // 
            filename: 'index.html', //   
        }),
    ],
}


Começamos a montagem. O diretório "dist" agora contém o arquivo "index.html" com o script incluído nele. Legal! Se você abrir este arquivo em um navegador, verá a mensagem "Que interessante!" no console.



Vamos adicionar algum conteúdo ao DOM. Vamos mudar o conteúdo do arquivo "index.js" e reiniciar a montagem.



// index.js
//   
const heading = document.createElement('h1')
heading.textContent = ' !'

//    DOM
const root = document.querySelector('#root')
root.append(heading)


Vá para o diretório "dist" e inicie o servidor (para isso, você precisa instalar globalmente o http-server : yarn global add http-server ou npm i -g http-server).



http-server


Na guia do navegador que é aberta, você verá um título que diz "Que interessante!" Observe também a redução no tamanho do arquivo.



Limpeza


Instale o plugin clean-webpack, que limpa o diretório "dist" toda vez que o projeto é construído. Isso permite que você exclua automaticamente arquivos antigos que não são mais necessários.





// webpack.config.js
const HtmlWebpackPlugin = require('html=webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

module.exports = {
    // ...

    plugins: [
        // ...
        new CleanWebpackPlugin(),
    ],
}


Módulos e carregadores



O webpack usa carregadores para analisar arquivos carregados por módulos . Eles podem ser arquivos JavaScript, recursos estáticos como imagens ou estilos e compiladores como TypeScript e Babel. O Webpack 5 possui vários carregadores de recursos integrados.



Nosso projeto tem um arquivo HTML que carrega algum script, mas não faz mais nada. Vamos pensar no que queremos do colecionador?



  • Compilar os recursos JavaScript mais recentes em um código compatível com todos ou a maioria dos navegadores
  • Importando estilos e convertendo SCSS em CSS
  • Importando imagens e fontes
  • Personalizando React ou Vue (opcional)


Primeiro, vamos configurar o Babel para compilar JavaScript.



Babel (JavaScript)


Babel é uma ferramenta para habilitar JavaScript futuro hoje.



Vamos definir uma regra de que todos os arquivos js em um projeto (exceto os arquivos contidos no diretório node_modules) serão transpilados usando o babel-loader. O Babel requer várias dependências para funcionar:





yarn add -D babel-loader @babel/core @babel/preset-env @babel/babel-plugin-proposal-class-properties


// webpack.config.js
module.exports = {
    // ...

    module: {
        rules: [
            // JavaScript
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader'],
            },
        ],
    }
}


Se você estiver configurando um projeto TypeScript, deverá usar o carregador de tiposcript em vez de carregador de babel para todos os arquivos JavaScript que precisam de transpilação. Você está verificando arquivos com a extensão "ts" e usando o ts-loader.



O Babel está configurado, mas o plugin ainda não está lá. Você pode verificar isso adicionando o seguinte código ao topo do index.js:



// index.js
//     
class Game {
    name = 'Violin Charades'
}
const myGame = new Game()

//  
const p = document.createElement('p')
p.textContent = `I like ${myGame.game}.`

//   
const heading = document.createElement('h1')
heading.textContent = ' !'

//      DOM
const root = document.querySelector('#root')
root.append(heading, p)


ERROR in ./src/index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/you/webpack-tutorial/src/index.js: Support for the experimental syntax 'classProperties' isn't currently enabled (3:8):

  1 | // Create a class property without a constructor
  2 | class Game {
> 3 |   name = 'Violin Charades'
    |        ^
  4 | }


Para corrigir isso, crie um arquivo ".babelrc" na raiz do projeto:



// .babelrc
{
  "presets": ["@babel/preset-env"],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}


Começamos a construção com a construção do fio. Tudo funciona agora.



Imagens


Queremos importar imagens para um arquivo JavaScript, mas o JavaScript não pode fazer isso. Para ter certeza disso, crie um diretório "src / images", coloque uma imagem lá e tente importá-la no arquivo "index.js":



// index.js
import example from './images/example.png'

// ...


Uma exceção será lançada ao iniciar a construção:



ERROR in ./src/images/example.png 1:0
Module parse failed: Unexpected character ' ' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders


Conforme observado anteriormente, o webpack possui alguns downloaders integrados para lidar com arquivos estáticos. Para imagens, use o tipo "ativo / recurso". Observe que estamos falando sobre o tipo (tipo), e não sobre o carregador (carregador):



// webpack.config.js
module.exports = {
    // ...

    module: {
        rules: [
            // 
            {
                test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
                type: 'asset/resource',
            },
        ],
    },
}


Um novo arquivo aparece no diretório "dist".



Fontes e outros dados incorporados


O webpack também possui um módulo integrado para lidar com alguns dados integrados, como fontes e SVG. Para isso, basta especificar o tipo "asset / inline":



// index.js
import example from './images/example.svg'

// ...


// webpack.config.js
module.exports = {
    // ...

    module: {
        rules: [
            //   SVG
            {
                test: /\.(woff(2)?|eot|ttf|otf|svg|)$/,
                type: 'asset/inline',
            },
        ],
    },
}


Estilos


Usar carregadores de estilo é um pré-requisito para usar strings como "import 'file.css'" em seu script.



Muitas pessoas usam CSS-in-JS , componentes estilizados e outras ferramentas que permitem o estilo JavaScript.



Às vezes, podemos nos limitar a carregar um arquivo CSS. Mas talvez você queira usar PostCSS , que permite os recursos CSS mais recentes no navegador. Ou você deseja usar o pré-processador Sass .



Quero usar todos os três - escrever código em Sass, processá-lo com PostCSS e compilar em CSS.





yarn add -D sass-loader postcss-loader css-loader style-loader postcss-preset-env node-sass


Assim como no Babel, PostCSS requer um arquivo de configuração separado:



// postcss.config.js
module.exports = {
    plugins: {
        'post-css-preset-env': {
            browsers: 'last 2 versions',
        },
    },
}


Para testar a funcionalidade das ferramentas nomeadas, vamos criar um arquivo "src / styles / main.scss" contendo variáveis ​​Sass e um exemplo de uso de PostCSS (lch):



// src/styles/main.css
$font-size: 1rem;
$font-color: lch(53 105 40);

html {
    font-size: $font-size;
    color: $font-color;
}


Importamos este arquivo para index.js e adicionamos 4 carregadores. Os carregadores são usados ​​pelo webpack da direita para a esquerda, então o último deve ser sass-loader, PostCSS, CSS e, finalmente, style-loader, que aplica estilos compilados a elementos DOM:



// index.js
import './styles/main.css'

// ...


// webpack.config.js
module.exports = {
    // ...

    module: {
        rules: [
            // CSS, PostCSS, Sass
            {
                test: /\.(scss|css)$/,
                use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],
            },
        ],
    },
}


Depois de construído, você notará que Sass e PostCSS foram aplicados ao DOM.



Observe que definimos as preferências para o modo de desenvolvimento. Para produção, use MiniCssExtractPlugin em vez de style-loader, que exporta CSS minimizado.



Desenvolvimento de



Digitar a construção do fio (npm run build) a cada vez para reconstruir o projeto pode ser entediante. Quanto maior o projeto, mais tempo demorará para ser construído. Portanto, você precisa ter dois arquivos de configuração do webpack:



  • Configurações de produção, incluindo minimização, otimização e remoção de todos os mapas de recursos (mapas de origem)
  • Configurações de desenvolvimento, incluindo início do servidor, atualização em cada mudança e mapas de recursos


Em vez de criar um diretório "dist", o modo de desenvolvimento pode esperar armazenar as informações de que você precisa na memória.



Para fazer isso, você precisa instalar o webpack-dev-server.





yarn add -D webpack-dev-server


Para demonstrar como usar um servidor para desenvolvimento, podemos definir as configurações apropriadas no arquivo webpack.config.js. Na prática, é melhor ter dois arquivos de configuração, um com modo: produção e outro com modo: desenvolvimento. No boilerplate webpack 5 especialmente preparado para você, eu uso webpack-merge para obter as configurações básicas em um único arquivo, e os requisitos especiais estão contidos nos arquivos "webpack.prod.js" e "webpack.dev.js".



// webpack.config.js
const webpack = require('webpack')

module.exports = {
    // ...
    mode: 'development',
    devServer: {
        historyApiFallback: true,
        contentBase: path.resolve(__dirname, './dist'),
        open: true,
        compress: true,
        hot: true,
        port: 8080,
    },
    plugins: [
        // ...
        //      
        new webpack.HotModuleReplacement(),
    ],
}


Adicionamos modo: desenvolvimento e uma propriedade "devServer". Esta propriedade contém várias configurações padrão - número da porta (8080), abertura automática do navegador, uso de substituição de módulo a quente , que requer webpack.HotModuleReplacement (). Isso permitirá que os módulos sejam atualizados sem uma recarga completa da página, ou seja, se os estilos individuais mudam, apenas eles são atualizados, você não precisa recarregar o JavaScript, o que acelera muito o desenvolvimento.



Para iniciar o servidor, use o comando "webpack serve":



// package.json
"scripts": {
    "start": "webpack serve"
}


yarn start


Depois de executar este comando, o navegador será aberto em localhost: 8080. Agora você pode modificar o Sass e o JavaScript e eles serão atualizados instantaneamente.



Conclusão



Espero que este artigo tenha ajudado você a começar com o webpack. Para facilitar a resolução de suas tarefas diárias, desenvolvi um webpack 5 boilerplate com Babel, Sass, PostCss, otimização para produção e um servidor para desenvolvimento. Tomando-o como base, você pode configurar facilmente seu webpack para funcionar com React, Vue ou TypeScript.



All Articles