Entenda os diferentes formatos de módulos javascript
Quando se trata de construir a sua aplicação, se for como eu, pergunte-se sempre: que formato devo usar ? CJS ? AMD ? UMD ? ESM ? Quais são as diferenças ? Porquê tantos formatos ?
Neste artigo, vou tentar responder a essas questões 😊.
#Os diferentes formatos
#CommonJS (CJS)
Este é um dos primeiros formatos criados. Tenho quase a certeza que já o usou. É o sistema de módulos que inicialmente inspirou o NodeJS.
Este sistema depende da importação e exportação de módulos graças a algumas palavras-chave bem conhecidas: require
e exports
. O objeto module.exports
é realmente específico do NodeJS.
// utils.js // we create a function function add(r){ return r + r; } // export (expose) add to other modules exports.add = add; // index.js var utils = require('./utils.js'); utils.add(4); // = 8
A equipe commonJS criou esta API como uma API síncrona que não é tão boa para navegadores… Além disso, Commonjs não é nativamente compreendido pelos navegadores; requer ou uma biblioteca de carregadores ou alguma transpiling.
#Asynchronous Module Definition (AMD)
AMD é algum tipo de divisão de CommonJS. Ele foi criado por membros da equipe CJS que discordaram da direção tomada pelo resto da equipe.
Foi decidido criar o AMD para suportar o carregamento assíncrono do módulo. Este é o sistema de módulos utilizado pelo RequireJS e que está funcionando no lado do cliente (em navegadores).
// add.js define(function() { return add = function(r) { return r + r; } }); // index.js define(function(require) { require('./add'); add(4); // = 8 }
Este exemplo só funciona se você tiver requirejs no seu site. Você pode encontrar alguns outros exemplos AMD.
#Universal Module Definition (UMD)
As you may have understood those 2 formats are unfortunately mutually unintelligible to each other. Esta é a razão pela qual o UMD foi criado. Ele é baseado no AMD mas com alguns casos especiais incluídos para lidar com a compatibilidade CommonJS.
Felizmente, esta compatibilidade adiciona alguma complexidade que torna a leitura/escrita complicada. Se você quiser, você pode encontrar múltiplos modelos de código UMD neste repositório do github.
#ES2015 Módulos (ESM)
Como esses 3 formatos não são tão fáceis de ler, difíceis de analisar para o analisador de código estático e não são suportados em todos os lugares, a equipe ECMA (a equipe por trás da padronização do Javascript) decidiu criar o padrão ECMAScript 2015 (também conhecido como ES6).Este formato é realmente simples de ler e escrever e suporta tanto o modo de operação síncrono como assíncrono.
// add.js export function add(r) { return r + r; } // index.js import add from "./add"; add(4); // = 8
Mais, os módulos es podem ser analisados estaticamente, o que permite que ferramentas de compilação (como Webpack ou Rollup) realizem trepidação de árvores no código. Tree-shaking é um processo que remove código não utilizado de bundles.
Felizmente, este formato ainda tem 2 contras (mas estão melhorando):
- ESM não suporta módulos importados dinamicamente, mas há uma proposta há meses que começou a ser implementada em alguns navegadores.
- Não é suportado em todos os browsers mas felizmente, isto pode ser “corrigido” graças a… transpiling !
#Transpiling
Transpiling é o processo de traduzir uma língua ou versão de uma língua para outra. Então aqui, a idéia é transpor o ES6 para o ES5 para obter um melhor suporte do navegador. Infelizmente, esta transposição tem um custo, pois adiciona algum código extra para corrigir as características ausentes do ES6 que não existem no ES5.
O transpiler mais famoso que é normalmente usado neste caso é o Babel.
#Outras leituras
Se você quiser ir mais longe (através de exemplos, explicações, etc.) para entender como esses diferentes formatos funcionam, aqui estão algumas leituras que eu encontrei e que me inspiraram:
- JavaScript Module Systems Showdown: CommonJS vs AMD vs ES2015
- Você deve usar esm
- Escrever JavaScript Modular Com AMD, CommonJS & ES Harmony
- O que é AMD, CommonJS, e UMD?
- Técnicas de modularização (há várias páginas aqui)
- O estado dos módulos JavaScript