Com a velocidade a qual o javascript avança, tendo versões anuais acrescentando funcionalidades, acabamos por adicionar um compilador (Babeljs o mais comum deles) em nosso workflow para usufruirmos de todas essas novidades e mantermos a compatibilidade, e isso não tem problema nenhum.
Junto ao compilador é comum usarmos também um bundler que se encarrega de gerar nosso código final aplicando diversas otimizações. O webpack é um dos mais conhecidos bundlers javascript atualmente, e ele por si só já oferece várias opções de otimização, mas temos que estar atentos às nossas configurações.
O webpack oferece uma funcionalidade chamada tree shaking. Ela é responsável por eliminação de código não utilizado no nosso bundle. Porém, com a utilização do babel-loader, precisamos configura-ló corretamente para não perder essa funcionalidade.
Como exemplo, vamos entender qual é o problema, para depois entendermos a solução.
Aqui basicamente é um exemplo com módulos javascript
Arquivo module.js
export const say = () => console.log('Say something')
export const scream = () => console.log('SCREAM SOMETHING')
Arquivo index.js
import { scream } from './module.js'
scream()
No index.js importamos somente a função scream
do arquivo module.js. Como nossa aplicação não usa a função say
, não faz sentido adicioná-la ao nosso bundle, e é isso o que faz o tree shaking do webpack. Porém nosso módulo utiliza algumas coisas que precisam ser compiladas pelo Babeljs para não preocuparmos com retrocompatibilidade, e é ai que temos que ter cuidado.
Geralmente nossa configuração do Babeljs é essa:
{
"presets": ["env"]
}
A única mudança que precisamos é setar o modules para false.
{
"presets": [
[
"env",
{
"modules": false
}
]
]
}
O que acontece é que o Babeljs compila o arquivo antes do webpack, e ele converte os módulos para CommonJS por default, e quando chega no webpack ele não consegue usufruir dos módulos nativos do javascript.
Esse é um exemplo simples, mas quando sua aplicação cresce e utiliza muitas libs, não faz sentido onerar muito o carregamento com código não utilizado.
Agora uma outra dica: muitos dos presets do Babeljs possuem um parâmetro chamado loose
, e o babel-preset-env é um deles. Basicamente o que acontece na compilação do Babeljs é que quando ele encontra uma funcionalidade não suportada na versão es5, ele compila essa parte do código para es5 mantendo a funcionalidade e semântica do código fonte no código compilado. O que o loose mode
faz é compilar para es5, porém não se importando tanto para a semântica, e muitas vezes ele gera um código muito menor. Como o nosso bundle vai ser interpretado diretamente no navegador ou no nodejs, não precisamos nos importar tanto com a semântica aqui, já que continuamos dando manutenção no arquivo fonte.
Para habilitar
{
"presets": [
[
"env",
{
"modules": false,
"loose": true
}
]
]
}
Para alguns exemplos de código gerado pelo loose mode
leia Babel: Loose mode.