Modularização
Modularizar uma aplicação significa organizar o seu código, talvez formado por milhares de linhas, em partes, os chamados módulos.
O conceito de modularização já é bem conhecido e existe há bastante tempo. "Ninguém" desenvolve grandes aplicações sem usar este conceito. Cada módulo é responsável por uma tarefa bem delimitada.
Naturalmente é bem mais fácil compreender, corrigir e atualizar um módulo do que ter que lidar com 100% do código. Mudanças feitas dentro de um módulo dificilmente afetarão a corretude de outros módulos.
JavaScript, curiosamente, só passou a incorporar o conceito de modularização a partir de 2015, com a especificação ES6. Até então para modularizar uma aplicação utilizava-se algum padrão. Os dois padrões mais conhecidos são o CommonJS Modules e o AMD(acrônimo para Asynchronous Module Definition). O primeiro foi popularizado pelo Node.js e o segundo tem em RequireJS a implementação mais conhecida.
Bibliotecas são módulos reutilizáveis. O desenvolvedor não precisa, na verdade não deve, "reinventar a roda". Basta "conectar" as bibliotecas ao sistema e muito tempo será poupado.
O grande problema é que os padróes de fato CommonJS e AMD são incompatíveis. A padronização definida em ES6 possibilita, a longo prazo, eliminar esta dificuldade. O efeito não é imediato pois existem, literalmente, milhões de bibliotecas usadas em larga escala e adotar o padrão ES6 iria "quebrar" as aplicações.
Módulos ES6
Módulos são armazenados em arquivos. Há um único arquivo para cada módulo e um único módulo em cada arquivo.
Um módulo pode definir funções, objetos, "classes", variáveis e constantes. Algumas destas definições podem ser exportadas, ou seja, podem ficar visíveis/disponíveis para o código que está utilizando o módulo. As demais definições são internas ao módulo e podem ser modificadas ou removidas livremente.
Definindo um Módulo
No módulo contido no arquivo lib1.js
a seguir estão definidas a constante gravitacional G e as funções media
e multiplica
:
Arquivo lib1.js:
const G = 9.8;
function media(n1, n2) {
return soma(n1 + n2) / 2;
}
function multiplica (n1, n2) {
return n1 * n2)
function soma(n1, n2) {
return n1 + n2;
}
export {G, media, multiplica};
A função soma
não é exportada pois ela existe apenas como parte da implementação da função media
.
Uma forma alternativa de dizer quais definições são exportadas pelo módulo é adicionando a palavra export
antes de cada definição. Por exemplo:
Arquivo lib1js:
export const G = 9.8;
export function media(n1, n2) {
return soma(n1 + n2) / 2;
}
export function multiplica (n1, n2) {
return n1 * n2)
function soma(n1, n2) {
return n1 + n2;
}
Usando um Módulo
Para usar um módulo é preciso importar as definições desejadas. Por exemplo, o programa definido no arquivo principal.js
abaixo usa a constante G
e a função media
definidas no módulo lib1.js
:
Arquivo principal.js:
import {G, media} from './lib1.js';
let r = media(G, 10);
console.log(r);
Módulos ES5
O conceito de módulo, mesmo tendo sido padronizado em 2015, ainda não é universalmente aceito. O Node.js, por exemplo, ainda só aceita módulos definidos no padrão CommonJS Modules. Alguns navegadores começam, só agora, a aceitar o padrão ES6.
Há duas formas para resolver esta situação:
- Desenvolver os módulos seguindo o padrão ES5
- Converter, via ferramenta automatizada, um módulo ES6 para o seu equivalente ES5. Uma das ferramentas mais usadas para isso é a Babel.
Definindo um Módulo ES5
O módulo lib1.js
padrão ES6 definido acima seria definido da seguinte forma no padrão ES5:
Arquivo lib1.js (padrão ES5):
const G = 9.8;
function media(n1, n2) {
return soma(n1 + n2) / 2;
}
function multiplica (n1, n2) {
return n1 * n2)
function soma(n1, n2) {
return n1 + n2;
}
module.exports = {
G: G,
media: media,
multiplica: multiplica
};
Usando um Módulo ES5
Para usar um módulo definido no padrão ES5:
Arquivo principal.js:
let G = require('./lib1.js').G;
let media = require('./lib1.js').media;
let r = media(G, 10);
console.log(r);
Leitura Sugerida |
---|
Explicando CommonJS e AMD |
Módulos ES6 e ES5 |