A diferença entre bibliotecas e frameworks JavaScript

Este artigo ensina as diferenças entre estruturas e bibliotecas no contexto de um ambiente JavaScript do lado do cliente, que é o código executado no navegador da Web. No entanto, alguns dos pontos levantados neste artigo também se aplicam a outros ambientes, porque bibliotecas e estruturas fazem parte de muitas áreas de engenharia de software, como o desenvolvimento de aplicativos nativos para dispositivos móveis.

As discussões nesta postagem se concentram nas diferenças qualitativas, e não nas quantitativas entre bibliotecas e frameworks. Exemplo:

  • Quantitativos:as estruturas normalmente adotam o princípio de inversão de controle.
  • Qualitativa:a experiência do framework pode atrair mais futuros empregadores quando você procurar emprego.

Por que aprender sobre bibliotecas e frameworks?

O uso da biblioteca e das estruturas do JavaScript é prolífico em toda a Web. Parece que todos os outros sites usam código de terceiros como parte dos recursos JavaScript. O peso da página da Web está piorando com o tempo, o que afeta os usuários. O JavaScript é um grande fator que contribui muito para o peso geral da página. É esse mesmo JavaScript que geralmente compreende bibliotecas e frameworks de terceiros.

Não é bom o suficiente dizer “Pare de usar estruturas do JavaScript”, porque as estruturas fornecem um grande benefício aos desenvolvedores. As estruturas podem ajudar você a codificar com eficiência e fornecer recursos rapidamente, entre outros benefícios. Em vez disso, você deve educar-se para que possa tomar uma decisão informada quando a hora chegar.

“Devo usar uma biblioteca ou estrutura hoje?” é uma pergunta incomum a se fazer. Bibliotecas e frameworks são duas coisas muito diferentes. No entanto, bibliotecas e estruturas costumam ser combinadas, e quanto mais conhecimento você tiver sobre os dois, maior será a probabilidade de tomar decisões informadas sobre o uso delas.

Exemplos de bibliotecas e frameworks

Talvez você note códigos de terceiros por outros nomes, como widgets, plug-ins, polyfills ou pacotes. No entanto, todos eles geralmente se enquadram na categoria de uma biblioteca ou framework. Basicamente, a diferença entre os dois pode ser resumida da seguinte forma:

Biblioteca

Bibliotecas tendem a ser mais simples do que estruturas e oferecem um escopo restrito de funcionalidade. Se você transmitir uma entrada para um método e receber uma saída, provavelmente usou uma biblioteca.

Confira este exemplo da biblioteca lodash:

import lodash from 'lodash'; // [1]
const result = lodash.capitalize('hello'); // [2]
console.log(result); // Hello

Como acontece com muitas bibliotecas, é prático ler esse código e entender o que ele faz. Há pouca mágica envolvida:

  1. Uma instrução import importa a biblioteca lodash para o programa JavaScript.
  2. O método capitalize() é invocado.
  3. Um único argumento é passado para o método.
  4. O valor de retorno é capturado em uma variável.

Framework

As estruturas tendem a ser maiores do que as bibliotecas e contribuem mais para o peso geral da página. Na verdade, um framework pode incluir uma biblioteca.

Este exemplo mostra um framework simples sem uma biblioteca e usa o Vue, que é um framework JavaScript popular:

<!-- index.html -->
<div id="main">
  {{ message }}
</div>

<script type="module">
import Vue from './node_modules/vue/dist/vue.esm.browser.js';

new Vue({
  el: '#main',
  data: {
    message: 'Hello, world'
  }
});
</script>

Se você comparar este exemplo de framework com o exemplo da biblioteca anterior, vai perceber estas diferenças:

  • O código do framework abrange várias técnicas e as abstrai em sua própria API opinativa.
  • Os desenvolvedores não têm controle total sobre como e quando as operações ocorrem. Por exemplo, como e quando o Vue grava a string 'Hello, world' na página, isso é ocultado de você.
  • A instanciação da classe Vue tem alguns efeitos colaterais, que são comuns quando você usa frameworks. Já uma biblioteca pode oferecer funções puras.
  • A estrutura prescreve um sistema específico de modelo HTML em vez de usar o seu próprio.
  • Se você ler mais a respeito da documentação do framework do Vue ou da maioria das outras documentações de framework, verá como as estruturas prescrevem padrões de arquitetura que podem ser usados. As estruturas de JavaScript tiram algum fardo cognitivo de você, porque não precisa descobrir isso por conta própria.

Quando usar uma biblioteca ou um framework

Depois de ler as comparações entre bibliotecas e frameworks, você pode começar a entender quando usar uma ou outra:

  • Um framework pode reduzir a complexidade para você, o desenvolvedor. Como discutido, um framework pode abstrair a lógica, o comportamento e até mesmo os padrões de arquitetura. Ela é especialmente útil quando você começa um novo projeto. Uma biblioteca pode ajudar com a complexidade, mas normalmente se concentra na reutilização do código.
  • Os autores de framework querem que você seja produtivo e muitas vezes desenvolvem ferramentas extras, software de depuração e guias abrangentes, entre outros recursos, para ajudar você a usar um framework de forma eficaz. Os autores de bibliotecas também querem que você seja produtivo, mas ferramentas especializadas são incomuns em bibliotecas.
  • A maioria das estruturas oferece um ponto de partida funcional, como um esqueleto ou padrão, para ajudar a criar aplicativos da Web rapidamente. Uma biblioteca se torna parte da sua base de código já estabelecida.
  • Em geral, as bibliotecas apresentam alguma complexidade à base de código. A complexidade nem sempre é óbvia no início, mas pode se revelar com o tempo.

Lembre-se de que você normalmente não compara uma biblioteca com um framework porque são coisas diferentes que realizam tarefas distintas. No entanto, quanto mais conhecimento você tiver sobre os dois, mais capacitado você terá para decidir qual é o melhor para você. A decisão de usar um framework ou biblioteca depende dos seus requisitos.

Possibilidade de troca

Você não vai mudar sua biblioteca ou framework toda semana. Porém, é recomendável entender as desvantagens de um pacote que bloqueia você no ecossistema dele. Também é recomendável entender que o desenvolvedor que decide usar um pacote de terceiros é, de alguma forma, responsável pela criação de um acoplamento flexível entre o pacote e o código-fonte do app.

Um pacote vinculado ao código-fonte é mais difícil de remover e trocar por outro. Pode ser necessário trocar um pacote quando:

  • É preciso fazer atualizações em um pacote que não está mais em manutenção.
  • Você descobre que o pacote tem bugs demais para ser usado.
  • Você descobre que um novo pacote atende melhor às suas necessidades.
  • Os requisitos do produto mudam, e o pacote não é mais necessário.

Veja este exemplo:

// header.js file
import color from '@package/set-color';
color('header', 'dark');

// article.js file
import color from '@package/set-color';
color('.article-post', 'dark');

// footer.js file
import color from '@package/set-color';
color('.footer-container', 'dark');

O exemplo anterior usa o pacote @package/set-color de terceiros em três arquivos separados. Se você trabalhar nesse código e precisar substituir o pacote de terceiros, atualize o código em três locais.

Como alternativa, é possível simplificar a manutenção e abstrair o uso da biblioteca para um só lugar, como mostrado neste exemplo:

// lib/set-color.js file
import color from '@package/set-color';

export default function color(element, theme = 'dark') {
  color(element, theme);
}

// header.js file
import color from './lib/set-color.js';
color('header');

// article.js file
import color from './lib/set-color.js';
color('.article-post');

// footer.js file
import color from './lib/set-color.js';
color('.footer-container');

No exemplo anterior, o uso direto da biblioteca é abstraído. Portanto, se você precisar trocar o pacote de terceiros, atualize apenas um arquivo. Além disso, agora é mais fácil trabalhar com o código, porque o arquivo set-color.js interno define um tema de cores padrão.

Facilidade de usar

Um framework pode ter uma API complexa, mas pode oferecer ferramentas para desenvolvedores que facilitam o uso geral. A facilidade de uso é baseada em muitos fatores e pode ser altamente subjetiva. Um framework pode ser difícil de usar porque:

  • O framework tem uma API inerentemente complexa.
  • O framework é mal documentado e requer muitas tentativas e erros para resolver problemas.
  • A estrutura usa técnicas que você e sua equipe desconhecem.

As estruturas podem mitigar esses desafios com práticas recomendadas comuns, como estas:

  • O framework oferece ferramentas de diagnóstico e desenvolvedor para facilitar a depuração.
  • O framework tem uma comunidade ativa de desenvolvedores que colaboram em documentação sem custo financeiro, guias, tutoriais e vídeos. Depois de consumir esse conteúdo, você estará produtivo com a estrutura.
  • O framework oferece uma API que segue as convenções de programação comuns. Você é produtivo com o framework porque aprendeu essas convenções anteriormente e está mais familiarizado com os estilos de programação.

Esses pontos são comumente atribuídos a frameworks, mas também podem ser atribuídos a bibliotecas. Por exemplo, a biblioteca JavaScript D3.js é eficiente e tem um grande ecossistema que oferece workshops, guias e documentação, entre outros recursos, que afetam a facilidade de uso.

Além disso, um framework geralmente prescreve uma arquitetura para seu app da Web, enquanto uma biblioteca normalmente é compatível com sua arquitetura atual, seja ela qual for.

Desempenho

Em geral, frameworks podem afetar mais o desempenho do que bibliotecas, embora haja exceções nesse caso. O desempenho da Web é uma área enorme com muitos tópicos, de modo que essas seções abordam dois tópicos importantes: tree shaking e atualizações de software.

Árvore tremendo

O agrupamento é apenas um aspecto do desempenho na Web, mas tem um grande efeito no desempenho, especialmente com bibliotecas maiores. O uso de tree shaking durante a importação e exportação melhora o desempenho porque encontra e remove códigos desnecessários para o app.

Ao agrupar o código JavaScript, há uma etapa útil, conhecida como tree shaking, que é uma valiosa otimização de desempenho que pode ser feita no código. No entanto, ela é mais fácil de fazer com bibliotecas do que com frameworks.

Ao importar código de terceiros para o código-fonte, você geralmente agrupa o código em um ou alguns arquivos de saída. Por exemplo, os arquivos header.js, footer.js e sidebar.js são combinados em um arquivo output.js, que é o arquivo de saída carregado no app da Web.

Para entender melhor o tree shaking, veja estes exemplos de código:

// library.js file
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

// main.js file
import {add} from './library.js';

console.log(add(7, 10));

Para fins de demonstração, o exemplo de código library.js é intencionalmente pequeno em comparação com o que você pode encontrar no mundo real, onde a biblioteca pode ter milhares de linhas.

Um processo de pacote simples pode exportar o código com esta saída:

// output.js file
function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

console.log(add(7, 10));

Mesmo que a função subtract() não seja necessária neste app, ela ainda está incluída no pacote final. Códigos desnecessários como esse aumentam o tamanho do download, o tempo de análise e compilação e os custos de execução que os usuários precisam pagar. Uma abordagem básica de tree shaking remove o código inativo e produz esta saída:

// output.js file
function add(a, b) {
  return a + b;
}

console.log(add(7, 10));

Observe que o código é mais curto e sucinto. Nesse exemplo, a melhoria no desempenho é insignificante, mas em um app real em que a biblioteca tem milhares de linhas, o efeito no desempenho pode ser muito mais significativo. As ferramentas de pacote modernas, como Parcel, Webpack e Rollup, vão além, porque combinam minificação e tree shaking para criar um pacote altamente otimizado. Para demonstrar a eficácia das ferramentas de pacote, usamos o Parcel (link em inglês) para criar um arquivo de pacote com os exemplos de código anteriores. O Parcel removeu todo o código não utilizado e exportou este único módulo:

console.log(7+10);

O pacote é inteligente o suficiente para remover instruções de importação, definições de função e comportamento, entre outros itens, para criar um código altamente otimizado.

O agrupamento é apenas um aspecto do desempenho na Web, mas tem um grande efeito no desempenho, especialmente com bibliotecas maiores. Normalmente, é mais simples fazer com bibliotecas do que com frameworks.

Atualizações de software

Para muitas bibliotecas e frameworks, as atualizações de software adicionam funcionalidades, corrigem bugs e aumentam de tamanho com o tempo. Nem sempre é necessário fazer o download de atualizações, mas se as atualizações incluírem correções de bugs, melhorias de recursos desejados ou correções de segurança, você provavelmente precisará atualizá-las. No entanto, quanto mais dados você enviar pela rede, menor será o desempenho do app e maior será o efeito de desempenho na experiência do usuário.

Se o tamanho de uma biblioteca for maior, use o tree shaking para reduzir esse crescimento. Também é possível usar uma alternativa menor à biblioteca JavaScript. Para mais informações, consulte Permutabilidade.

Se um framework crescer de tamanho, além de "tree shaking" ser mais um desafio, será mais difícil trocar um por outro. Para mais informações, consulte Permutabilidade.

Empregabilidade

É como um segredo aberto que muitas empresas têm requisitos rígidos para desenvolvedores que conhecem uma estrutura específica. Eles podem desconsiderar seu conhecimento sobre os fundamentos da Web e se concentrar apenas no seu conhecimento específico sobre uma determinada estrutura de JavaScript. Certo ou errado, essa é a realidade para muitos trabalhos.

O conhecimento de algumas bibliotecas JavaScript não prejudicará sua candidatura, mas há poucas garantias de que isso fará você se destacar. Se você conhece algumas estruturas populares de JavaScript muito bem, há uma boa chance de que os empregadores considerem esse conhecimento favorável no mercado de trabalho atual para desenvolvedores web. Algumas grandes organizações empresariais ficam presas a estruturas muito antigas de JavaScript e podem até mesmo desesperar os candidatos que se sentem confortáveis com essas estruturas.

Você pode usar esse segredo aberto a seu favor. No entanto, aborde o mercado de trabalho com cuidado e pensando no seguinte:

  • Lembre-se de que, se você passar muito tempo na carreira com apenas uma estrutura, poderá perder experiências de aprendizado com outras estruturas mais modernas.
  • Considere um desenvolvedor que não entende firmemente o desenvolvimento de software ou os fundamentos do desenvolvimento da Web, mas que é contratado como desenvolvedor de framework. Esse desenvolvedor não escreve código eficaz, e você pode achar difícil ou estressante trabalhar com essa base de código. Em alguns casos, este cenário pode levar ao esgotamento. Por exemplo, talvez seja necessário refatorar o código ou ajustar o desempenho dele por ser lento.
  • Ao aprender sobre desenvolvimento na Web, o melhor caminho é começar com um foco significativo nos fundamentos de desenvolvimento da Web, desenvolvimento de software e engenharia de software. Uma base forte como essa ajuda você a escolher qualquer estrutura de JavaScript de forma rápida e eficaz.

Conclusão

Parabéns pelo seu trabalho árduo para entender a comparação entre os frameworks e as bibliotecas JavaScript. Você não escolherá frameworks ou bibliotecas com frequência, a menos que trabalhe em projetos novos ou como consultor. No entanto, quando essas decisões surgem, quanto mais conhecimento você tiver sobre o assunto, melhor será a sua decisão.

Como você aprendeu, a escolha do framework e, em alguns casos, a escolha da biblioteca, pode afetar significativamente sua experiência de desenvolvimento e os usuários finais, como o desempenho.