Babel: Loose mode

Saudações, pessoal! Neste artigo, iremos abordar algo que não é muito utilizado nem muito conhecido pela comunidade. Babel possui features incríveis e devemos dar mais atenção a elas para aproveitarmos o máximo que essa ferramenta oferece.

Aqui na ZUP, no projeto em que trabalho, precisei encontrar algumas formas para podermos diminuir o bundle size da nossa aplicação. Então, foi necessário pesquisar e esta foi uma das várias formas que encontramos.

Loose mode está contido em vários plugins do Babel e presets e, com uma simples configuração, você poderá desfrutar de um grande desempenho.

O Básico

Antes de entrarmos em mais detalhes, vamos dar uma descrição sobre o que é este modo.

Como já foi descrito anteriormente, loose mode é uma opção presente em alguns plugins do Babel para transpilar a nova geração de ES6 para ES5. O resultado poderá ser notado no código transpilado.

Imagine a possibilidade de chegar em um mesmo resultado com uma quantidade menor de código. Isso impacta diretamente o size do seu bundler final e você ganha performance teoricamente.

Resultado

Com loose mode, o código também é transpilado para ES5, porém o resultado não é fiel semanticamente ao código de origem. Mais a frente, iremos exemplificar algumas das features mais utilizadas e demonstrar a saída dos dois modos, ES5 com e sem loose mode.

Resumo:

  • ES5: gera um código o mais fiel possível semanticamente ao código escrito em ES6.
  • ES5 Loose mode: gera um simples código ES5, porém não fiel ao código escrito.

Quais plugins possuem?

Muitos plugins babel possuem essa opção. Aqui estão alguns deles:

  • transform-es2015-template-literals
  • transform-es2015-classes
  • transform-es2015-computed-properties
  • transform-es2015-for-of
  • transform-es2015-spread
  • transform-es2015-destructuring
  • transform-es2015-modules-commonjs

Let’s GO!

Irei demonstrar exemplos de transformações que considerei ter um maior impacto no bundle size.

Transform-es2015-classes

Neste, vamos ver como será o efeito deste modo na transpilação utilizando uma classe que aqui nomeei como PersonClass. No Construtor, ele recebe um nome e temos um método que retorna o nome no console.

Entrada:

Saída ES5:

Saída ES5 Loose:

É impressionante como aqui podemos ter a mesma lógica que o código anterior, porém muito mais clean.

Transform-es2015-template-literals/Transform-es2015-computed-properties

Neste, vamos ver qual será o efeito deste modo na transpilação utilizando template literals e computed properties.

O exemplo é uma função que recebe dois parâmetros e o retorno é um object. O primeiro parâmetro é a propriedade e o outro o valor da propriedade. A segunda propriedade está concatenando uma string qualquer utilizando template literals.

Entrada:

Saída ES5:

Saída ES5 Loose:

Como utilizar?

Em seu arquivo de configuração do Babel, você deverá mencionar que a sua transpilação irá utilizar o loose mode.

Caso você queira transpilar somente alguma feature, você pode optar por plugins e habilitar o loose somente em seu plugin.

Com plugins:

{
"plugins": [
["transform-es2015-classes", {
"loose": true
}]
]
}

Com presets: Assim como os plugins, não são todos os presets que possuem tal modo. É necessário verificar a documentação do preset para consultar a informação. Neste exemplo citei o preset es2015, mas o loose mode também está presente no env.

{
"presets": [
["es2015", {
loose: true
}]
]
}

Pros / Con

Dr. Axel Rauschmayer em um artigo relatou que este modo não é recomendado e postou sua posição sobre prós em contras deste modo.

Pros: Gera um código potencialmente mais rápido e mais compatível com antigos projetos e tende a ser mais limpo.

Con: Você arrisca a obter problemas mais tarde, quando você mudar de ES6 transpilado para ES6 nativo.

Com relação ao que é relatado na contraposição, ele cita que você pode obter um efeito distinto, caso um dia você venha a parar de transpilar o seu código. Possivelmente acreditando que possa haver efeitos colaterais no comportamento das features que anteriormente eram transpilados.

Quem usa?

Fiz uma pequena pesquisa e encontrei várias libs conhecidas da comunidade que utilizam loose mode.

  • Preact
     Fast 3kB alternative to React with the same modern API.
  • Redux
     
    Redux is a predictable state container for JavaScript apps.
  • React
     
    A JavaScript library for building user interfaces
  • React-Router
     
    Declarative routing for React