Front End

13 mar, 2019

Configurando Alias no Webpack

Publicidade

Criar aplicações e projetos front-end é fácil, o difícil é organizar, estruturar e arquitetar. Muitas vezes alguns detalhes acabam passando despercebidos e poderiam facilmente ser resolvidos.

Quando trabalhamos em projetos front-end utilizando bibliotecas ou frameworks, como: React, Angular ou Vue, usamos muito os módulos para deixar nossos projetos modularizados.

Mas nem tudo são flores. Podemos facilmente encontrar componentes ou arquivos com as seguintes importações:

import { sum } from '../../../../../utils/numeros'
import App from '../../../containers/App'
import ComponentaA from '../../../../componentes/ComponenteA'

Veja o quanto é ruim esse código acima. Podemos destacar alguns pontos:

  • Precisamos voltar todas as pastas até encontrar os diretórios que precisamos
  • Estamos criando um vínculo muito forte entre estrutura e arquivos

Antes de tentarmos procurar soluções, vamos entender cada um dos problemas mencionados

Encontrar os diretórios que precisamos

Ter a necessidade de ir voltando e subindo o nível de todas as pastas até encontrarmos o diretório que estamos procurando é muito chato.

Muitas vezes estamos em pastas de quinto nível e precisamos voltar para a raiz. Assim, surge a necessidade de colocar infinitos ../, o que não é só feio como também ruim e cansativo.

Vínculo muito forte entre estrutura e arquivos

Criar esse vínculo pode ser perigoso, pois caso surja a necessidade de trocar a pasta componentes para inglês (components), vamos precisar arrumar em todos nossos arquivos (sim, pode ser feito de maneira automática).

Além disso, se um dia precisarmos criar uma nova pasta pai de componentes, também teremos retrabalho e manutenção.

Veja que independente do cenário – por ter esse vínculo muito forte, qualquer mudança na estrutura irá gerar uma manutenção (às vezes grande).

Agora que entendemos um pouco mais sobre ambos os problemas, como será que podemos resolvê-los?

Para isso, podemos fazer uso do Webpack – mais especificamente, podemos configurar os alias (apelidos/paths simbólicos).

Para realizar a configuração dos apelidos (gosto de chamar de path simbólicos), precisamos abrir nosso webpack.config.js, e na raiz do objeto de configuração começamos adicionando uma chave chamada resolve.

module.exports = {
    // configurações otimidas
    resolve: { }
}

Agora, dentro do resolve, precisamos adicionar uma propriedade chamada alias:

module.exports = {
    // configurações otimidas
    resolve: {
        alias: { }
    }
}

E dentro do nosso alias será onde vamos definir todos os apelidos ou path simbólicos. Vamos começar definindo três paths referentes ao exemplo anterior de importação, sendo eles: utils, containers e componentes.

const path = require('path')

module.exports = {
    // configurações otimidas
    resolve: {
        alias: {
            '@components': path.resolve(__dirname, 'src', 'componentes'),
            '@containers': path.resolve(__dirname, 'src', 'containers'),
            '@utils': path.resolve(__dirname, 'src', 'utils')
        }
    }
}

Maravilha, agora dentro dos nossos arquivos podemos mudar as importações para:

import { sum } from '@utils/numeros'
import App from '@containers/App'
import ComponentaA from '@components/ComponenteA'

Veja que ficou muito mais simples, fácil e prático. Além desses ganhos, se um dia a pasta componentes mudar para components, precisamos apenas atualizar nosso alias, e o resto da aplicação continuará funcionando e não exigirá manutenção, retrabalho ou find em arquivos .js.

Saiba mais

Se você é atento, deve ter reparado no @ em todos os paths. Eu gosto de defini-los para deixar explicito que trata-se de um alias ou path simbólico. Além disso, sem o @ podemos encontrar alguns conflitos. Por exemplo:

import { history } from 'history`

Dessa maneira, não estamos importando o nosso objeto history, e sim o pacote history instalado através de npm. Portanto, se adicionarmos o @:

import { history } from '@history`

Agora sim, não terá o conflito e estamos importando o nosso objeto.

Por se tratar de uma configuração feita no Webpack e diversas aplicações hoje em dia utilizarem o mesmo, a criação e definição dos alias pode ser feita em projetos com React, Angular e Vue sem o menor problema, mas claro que cada um terá seu jeito de ser configurado. Vamos ver alguns exemplos?

Configurando no React

Para realizar a configuração dos alias em projetos React existem duas maneiras:

  • Projetos criados com create-react-app com versão menor que a 2. Ou seja, version < 2.
  • Projetos criados com create-react-app com versão maior ou igual que a 2. Ou seja, version >= 2.

Vamos aos exemplos de cada um deles.

Precisamos começar ejetando as configuração padrão do projeto. Isso pode ser feito através do comando eject:

yarn eject

Ou com npm:

npm run eject

Observação: garanta que o projeto esteja comitado – caso contrário apresentará alguns problemas.

Após realizar o eject e ser finalizado, em projetos com a versão 1.x do create-react-app, uma pasta config será criada na raiz do projeto. Dentro dela, teremos dois arquivos responsáveis pelas configurações do Webpack, sendo eles:

  • webpack.config.dev.js
  • webpack.config.prod.js

O próprio nome já diz, o .dev.js será configurado para ambiente de desenvolvimento e o .propd.js para realizar o build final do projeto.

Dentro de cada um deles temos a opção resolve, e dentro dela a opção alias (com valores defaults). O resto vocês já sabem fazer, não muda da maneira que fizemos no começo.

Em projetos que possuem a versão 2.x do create-react-app, ao ejetar as configurações, também será criada uma pasta chamada config.

Porém, dentro dela terá apenas um arquivo webpack.config.js. O mesmo serve tanto para dev quando para prod. O resto das configurações é igual, procure a opção resolve e dentro dela o alias.

Configurando no Angular

No Angular, apesar de também utilizar Webpack, essa configuração pode ser feita no tsconfig.json. Para que tudo funcione, precisamos configurar duas propriedades: baseUrl e paths.

A propriedade baseUrl definirá a pasta base para montar os paths. Por exemplo:

{
    "baseUrl": "./src"
}

Estamos dizendo que nossos paths devem ser procurados dentro da pasta src. Agora, através da propriedade paths podemos criar os apelidos:

{
    "baseUrl": "./src",
    "paths": {
        "@components/*": [ "app/components/*" ],
        "@containers/*": [ "app/containers/*" ],
        "@utils/*": [ "app/utils/*" ]
    }
}

Repare que precisamos colocar o * tanto na definição do path como na busca. O mesmo deve para pegar tudo que vier depois de @components. Exemplo:

import ComponentaA from '@components/ComponenteA'

Neste exemplo o * será ComponenteA. Portanto, nosso path ficaria:

"@components/ComponenteA": [ "app/components/ComponenteA" ]

Lembrando que o mesmo será procurando dentro de src. Sendo assim, o path final ficaria:

  • src/app/components/ComponenteA

Configurando no Vue

Para configurar os alias no Vue é bem similar ao React. Oprimeiro passo será criar um arquivo vue.config.js na raiz do projeto.

Ele será o responsável por adicionar novas configurações no Webpack. Dentro dele devemos exportar um objeto JSON contendo as propriedades resolve e alias, assim como no React:

const path = require('path')

module.exports = {
    configureWebpack: {
        resolve: {
            alias: {
                '@components': path.resolve(__dirname, 'src', 'components')
            }
        }
    }
}

Repare que, para merger nossa configuração com a configuração atual do Webpack, precisamos criar uma chave configureWebpack, e dentro dela adicionar o que precisamos. Assim, o Vue irá pegar as configurações padrões e mergear com a nossa.

Saiba mais

Alguns paths que geralmente eu crio nos projetos:

'@': path.resolve(__dirname, '..', 'src'),
'@cfg': path.resolve(__dirname, '..', 'src', '_config'),
'@components': path.resolve(__dirname, '..', 'src', 'components'),
'@config': path.resolve(__dirname, '..', 'src', '_config', 'config'),
'@constants': path.resolve(__dirname, '..', 'src', 'constants'),
'@containers': path.resolve(__dirname, '..', 'src', 'containers'),
'@css': path.resolve(__dirname, '..', 'src', '_assets', 'css'),
'@env': path.resolve(__dirname, '..', 'src', '_environments'),
'@features': path.resolve(__dirname, '..', 'src', 'features'),
'@fonts': path.resolve(__dirname, '..', 'src', '_assets', 'fonts'),
'@helpers': path.resolve(__dirname, '..', 'src', 'helpers'),
'@hoc': path.resolve(__dirname, '..', 'src', 'hoc'),
'@http': path.resolve(__dirname, '..', 'src', '_config', 'http'),
'@i18n': path.resolve(__dirname, '..', 'src', '_translate', 'i18n'),
'@icons': path.resolve(__dirname, '..', 'src', '_assets', 'icons'),
'@img': path.resolve(__dirname, '..', 'src', '_assets', 'img'),
'@js': path.resolve(__dirname, '..', 'src', '_assets', 'js'),
'@mocks': path.resolve(__dirname, '..', 'src', '_config', 'mocks'),
'@routes': path.resolve(__dirname, '..', 'src', '_config', 'routes'),
'@utils': path.resolve(__dirname, '..', 'src', 'utils')

Se você não entende o porquê desse monte de path, dê uma olhada no artigo “Como organizar projetos em React“. Nele eu dou dicas de como estruturar projetos React.

Conclusão

Nesse artigo mostrei como configurar alias dentro do Webpack de forma nativa, mas também vimos as mesmas configurações para React, Angular e Vue. Geralmente eu prefiro chamar esses “apelidos” de “links simbólicos”.

E aí, você já conhecia o alias? Não deixe de comentar!

Até a próxima!