Como Funciona a Transpilação De Código Do Babel
Hoje em dia quando estamos trabalhando com a linguagem JavaScript, é comum utilizarmos seus recursos, funcionalidades e sintaxes modernas. Porém, esse uso pode acabar trazendo problemas de compatibilidade entre navegadores. Vamos imaginar o seguinte cenário:
Precisamos criar uma função que irá receber um nome como parâmetro e retornar uma mensagem: Olá, NOME
, onde NOME
será o nome passado como parâmetro. Podemos fazer algo parecido com:
const ola = nome => `Olá, ${nome}`
Poderíamos fazer essa implementação de vários jeitos, mas optei por essa.
Legal! Vamos testá-la?
console.log(ola('Matheus'))
Teremos a saída Olá, Matheus
em nosso console.
Então temos a função e tudo está funcionando. Assim, já podemos entregar nossa feature, certo? Sim, mas a função foi testada em um navegador atualizado (moderno), no caso, o Google Chrome v74.0.3729. Agora vai a pergunta:
Será que nossa função funciona de maneira correta em outros navegadores?
Se a testarmos no Firefix e Safari (poderíamos testar em mais), ela irá funcionar da mesma maneira, porém, se testarmos ela no Internet Explorer 11(IE11) a mesma não irá funcionar. Vamos ter um erro referente a sintaxe do nosso código.
Por que isso está acontecendo? O que acontece é que até o momento, o IE11 ainda não implementou ou adicionou compatibilidade para o uso de const.
Dessa maneira, ele não entende esse trecho de código.
Como podemos resolver esse problema? Uma solução bem simples será a gente trocar a const
por algo que ele entenda. No caso, poderíamos substituir o uso de const
por var
:
var ola = nome => `Olá, ${nome}`
Porém, agora vamos ter outro problema que é referente ao uso da arrow function. Ele também não entende e não sabe interpretar esse trecho de código. Assim como fizemos para o const
, vamos trocar a arrow function por uma função normal do JavaScript:
var ola = function(nome) {
return `Olá, ${nome}`
}
Maravilha, agora nosso código irá funcionar tanto para os navegadores modernos quanto para os antigos.
Mas, será que realmente precisamos abrir mão de utilizar códigos e recursos novos para dar suporte a navegadores antigos? Será que nossos usuários irão utilizar navegadores como Internet Explorer?
Abrir mão de um ou outro pode acabar não sendo a melhor das opções, então, será que não existe alguma maneira de termos os dois? Existe, para isso que foi criado o Babel.
Conhecendo o Babel
O Babel é um compilador JavaScript, ou seja, com ele a gente consegue converter códigos modernos do JavaScript para códigos mais antigos. Esse processo de ler um código novo e converter para velho é chamado de transpilação, ou seja, ele vai transpilar nosso código novo para um antigo. Dessa maneira, conseguimos escrever nossos códigos fontes em versões mais novas, como no primeiro exemplo:
const ola = nome => `Olá, ${nome}`
E pedir para o Babel transpilar esse código moderno para algo mais antigo:
"use strict";var ola = function ola(nome) {
return "Ol\xE1, ".concat(nome);
};
Sim, esse será o código transpilado. Se você quiser testar, o Babel tem um repl onde é possível fazer testes online.
Legal, conseguimos atingir o objetivo que queríamos. Vamos escrever códigos novos e ainda teremos compatibilidade com navegadores mais antigos.
Mas como o Babel faz essa transpilação?
Entendendo a transpilação
A transpilação é algo mágico? Simplesmente recebe um código e sai outro? Como funciona o processo? Perguntas como essas eu irei tentar responder ao longo do post.
Para que o Babel consiga fazer esse processo de transpilação, alguns passos são necessários, sendo eles:
- Traverse
- Generate
Calma, a gente vai entender cada um deles.
Parser
O primeiro passo referente ao Parser é onde o parser
do Babel irá parsear o código JavaScript para uma estrutura chamada AST ( Abstract Syntax Tree). Para esse processo de parseamento é utilizado o @babel/parser
.
A ideia desse passo é mapear todo o nosso código JavaScript em pequenos nós, onde cada nó é uma representação do nosso código e esses nós são conectados uns aos outros.
Dado o nosso exemplo:
const ola = nome => `Olá, ${nome}`
Vamos ver como fica a AST dele?
Caso a imagem esteja muito pequeno o exemplo pode ser encontrado aqui.
Se você quiser ver a AST dos seus códigos, pode estar usando o https://astexplorer.net/.
Repare que no body
do Program
a gente tem um nó referente à declaração de variável VariableDeclaration
, depois temos um nó para a nossa arrow function ArrowFunctionExpression
e por fim temos o nó referente a template string TemplateLiteral
.
Com isso, o Babel já sabe onde está cada nó em nosso código fonte (linhas e colunas) e sabe como deve substítuí-los.
Traverse
Nesse momento a AST montada anteriormente está sendo manipulada para gerar uma nova referente ao código transpilado. Basicamente ele vai substituir os nós modernos pelos nós antigos. O pacote responsável por esse passo é o @babel/traverse
.
Generate
Esse é o último passo. O generate basicamente vai pegar a nova AST e voltá-la para código JavaScript. O pacote responsável por esse passo é o @babel/generator
.
Resumindo, é assim que funciona o processo de transpilação de um código JavaScript moderno para um código JavaScript antigo feito pelo Babel.
Saiba mais
Apenas a título de curiosidade, não só o Babel faz esse processo de montar um AST a partir de um código fonte. Outros compiladores também fazem isso. A V8
da Google por exemplo, faz algo parecido durante a execução de JavaScript no navegador Google Chrome (assunto para o próximo post).
Conclusão
Nesse post expliquei como é o processo de transpilação de um código JavaScript moderno para um código antigo feito pelo Babel, também vimos o que são as AST’s e porque elas são necessárias.
E aí, você já sabia como era feita essa transpilação? Não deixe de comentar.
Caso tenha gostado desse post, você pode estar assinando nossa newsletter e ficar por dentro das novidades.
Abraços, até a próxima.
Publicado originalmente em https://blog.matheuscastiglioni.com.br dia 13 de Junho de 2019.