Front End

16 ago, 2019

Como funciona a transpilação de código do Babel

Publicidade

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, eu optei por essa.

Legal, vamos testá-la?

console.log(ola('Matheus'))

Teremos a saída Olá, Matheus em nosso console.

Comemorando o sucesso da função

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?

Gif pensando na pergunta

Se 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.

Porque 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 iram 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 ao 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 replonde é 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.

Comemorando a apresentação do Babel

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 testar responder ao longo do post.

Para que o Babel consiga fazer esse processo de transpilação, alguns passos são necessários, sendo eles:

Passos para a transpilação do Babel

Sendo eles:

  1. Parser
  2. Traverse
  3. 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 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?

AST do nosso exemplo

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 a declaração de variável VariableDeclaration, depois temos um nó para a nossa arrow functionArrowFunctionExpression e por fim temos o nó referente a template stringTemplateLiteral.

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 para 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.

Basicamente é 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 á título de curiosidade, não só o Babel faz esse processo de montar um AST á partir de um código fonte, outros compiladores também fazem isso, a V8da 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.

Referências: