Executando verificação de segurança...
6

Dúvida: CommonJS ou ES modules

Sempre que eu inicio um projeto e preciso olhar documentações de alguma lib, me deparo com algo como const lib = require('lib'). E sempre me perguntei a diferença de usar isso e o famoso import {} from 'lib'. Bom, um tempo atrás eu dei uma pesquisada e descobri que a diferença é basicamente que um veio para substituir o outro, o ES modules veio como uma 'evolução' do CommonJS (não tenho certeza nem propriedade para afirmar isso, é apenas oque eu lembro e entendi). A duvida que fica é: Porque ainda encontro muitas pessoas/documentações utilizando CommonJS????

Carregando publicação patrocinada...
7

descobri que a diferença é basicamente que um veio para substituir o outro

Não é bem isso, tem várias diferenças:

  1. require é síncrono, import é assíncrono
  2. require é compilado e executado assim que carregado, import é compilado quando carregado e executado quando necessário
  3. require é backend e emulado no front, precisa de webpack pra funcionar, import funciona no backend e no front
  4. require pode causar poluição de escopo global e reimportação de dependências circulares, importevita isso e você precisa explícitamente (ou seja manualmente) injetar os valores no escopo global

Porque ainda encontro muitas pessoas/documentações utilizando CommonJS????

N motivos:

  1. import não é uma substituição direta de require, é uma alternativa padronizada mais moderna
  2. ESM 6 não são diretamente compatíveis, e como tem muito projeto legado, não vai ter essa unificação tão cedo
  3. require é nítidamente mais prático que import, para um projeto pequeno import pode ser overengineering
  4. Webpack e Babel podem unificar os dois padrões e quando fazem isso, fazem para require
  5. O comportamento assincrono de import pode ser inconveniente as vezes

A recomendação mais óbvia é: Aprenda e pratique os 2 porque na próxima década require mesmo que perca força vai ser muito usado

2

a questão de projetos legados realmente faz muito sentido, mas não consigo pensar em um exemplo em que o carregamento assíncrono seria um problema, ja que isso veio pra melhorar o desempenho creio eu, poderia me dar algum exemplo?

2

mas não consigo pensar em um exemplo em que o carregamento assíncrono seria um problema, ja que isso veio pra melhorar o desempenho creio eu, poderia me dar algum exemplo?

Tem muita confusão sobre isso, assincronismo não necessariamente melhora o desempenho, mas um exemplo é onde você configura dinamicamente o servidor ou página, import mais atrapalha que ajuda, você basimente vai precisar deixar o import sincrono e isso tem um custo tanto de legibilidade código quanto de desempenho (nesse exemplo é irrelevante mas adiciona uns milissegundos a mais):

(async () => {
  const meuSetup = await import('./meuSetup.js');
  meuSetup.init();
  
  // Resto do script
})();

Em CommonJS:

const meuSetup = require('./meuSetup.js');
meuSetup.init();

Sobre minha afirmação sobre async não necessáriamente ser mais rápido:

async function processaNumeros(array) {
  return await array.map(async (numero) => {
    return numero * 2;
  });
}

(async function() {
  const numeros = [1, 2, 3, 4, 5];
  const resultados = await processaNumeros(numeros);

  console.log(resultados);
})();

Note que por eu ter uma operação sincrona eu não vou ter o resultado esperado, eu preciso modificar processaNumeros para resolver as promisses antes de retornar:

async function processaNumeros(array) {
  const resultados = await Promise.all(
    array.map(async (numero) => {
      return numero * 2;
    })
  );
  return resultados;
}

E isso é consideravelmente mais lento que:

function processaNumeros(array) {
  return array.map((numero) => {
    return numero * 2;
  });
}

(function() {
  const numeros = [1, 2, 3, 4, 5];
  const resultados = processaNumeros(numeros);

  console.log(resultados);
})();

Via de regra tudo que tem operações síncronas vai necessessariamente tornar o uso de async mais lento, claro que esse exemplo não acontece diretamente na vida real eu só mandei porque ele permite visualizar a situação, mas internamente acontece muito, por exemplo, imagina uma função async que faz uma requisição que retorna um json e processa diretamente o json, ela vai ser geralmente mais lenta que usar duas funções uma assincrona para a requisição e outra sincrona para processar, o motivo fica ilustrado no exemplo acima

1