Uma introdução aos sistemas de módulos em JavaScript

Uma introdução aos sistemas de módulos em JavaScript

O conceito de módulos vem do paradigma de programação modular. Este paradigma propõe que o software deve ser composto de componentes separados e intercambiáveis ​​chamados “módulos”, dividindo as funções do programa em arquivos autônomos que podem funcionar separadamente ou acoplados em um aplicativo.





MAKEUSEO VÍDEO DO DIA

Um módulo é um arquivo autônomo que encapsula código para implementar determinada funcionalidade e promover a reutilização e a organização.





Aqui você abordará os sistemas de módulo usados ​​em aplicativos JavaScript, incluindo o padrão de módulo, o sistema de módulo CommonJS usado na maioria dos aplicativos Node.js e o sistema de módulo ES6.





O Padrão do Módulo

Antes da introdução dos módulos JavaScript nativos, o padrão de design do módulo era usado como um sistema de módulos para definir o escopo de variáveis ​​e funções para um único arquivo.

Isso foi implementado usando expressões de função imediatamente invocadas, popularmente conhecidas como IIFEs. Um IIFE é uma função não reutilizável que é executada assim que é criada.



Aqui está a estrutura básica de um IIFE:

(function () { 
//code here
})();

(() => {
//code here
})();

(async () => {
//code here
})();

O bloco de código acima descreve os IIFEs usados ​​em três contextos diferentes.





Os IIFEs foram usados ​​porque as variáveis ​​declaradas dentro de uma função têm o escopo da função, tornando-as acessíveis apenas dentro da função, e porque as funções permitem retornar dados (tornando-os publicamente acessíveis).

Por exemplo:





const foo = (function () { 
const sayName = (name) => {
console.log(`Hey, my name is ${name}`);
};
//Exposing the variables
return {
callSayName: (name) => sayName(name),
};
})();
//Accessing exposed methods
foo.callSayName("Bar");

O bloco de código acima é um exemplo de como os módulos foram criados antes da introdução dos módulos JavaScript nativos.

windows 10 definir gif como plano de fundo

O bloco de código acima contém um IIFE. O IIFE contém uma função que torna acessível retornando-a. Todas as variáveis ​​declaradas no IIFE são protegidas do escopo global. Assim, o método ( digaNome ) só é acessível através da função pública, callSayName .

Observe que o IIFE é salvo em uma variável, foo . Isso porque, sem uma variável apontando para sua localização na memória, as variáveis ​​ficarão inacessíveis após a execução do script. Este padrão é possível devido Fechamentos de JavaScript .

O sistema de módulos CommonJS

O sistema de módulos CommonJS é um formato de módulo definido pelo grupo CommonJS para resolver problemas de escopo JavaScript executando cada módulo em seu namespace.

O sistema de módulos CommonJS funciona forçando os módulos a exportar explicitamente as variáveis ​​que desejam expor para outros módulos.

Este sistema de módulos foi criado para JavaScript do lado do servidor (Node.js) e, como tal, não é suportado por padrão em navegadores.

Para implementar módulos CommonJS em seu projeto, você deve primeiro inicializar o NPM em seu aplicativo executando:

npm init -y 

Variáveis ​​exportadas seguindo o sistema de módulos CommonJS podem ser importadas assim:

//randomModule.js 
//installed package
const installedImport = require("package-name");
//local module
const localImport = require("/path-to-module");

Os módulos são importados no CommonJS usando o exigir instrução, que lê um arquivo JavaScript, executa o arquivo de leitura e retorna o exportações objeto. o exportações O objeto contém todas as exportações disponíveis no módulo.

Você pode exportar uma variável seguindo o sistema de módulos CommonJS usando exportações nomeadas ou exportações padrão.

Exportações nomeadas

As exportações nomeadas são exportações identificadas pelos nomes que lhes foram atribuídos. As exportações nomeadas permitem várias exportações por módulo, ao contrário das exportações padrão.

Por exemplo:

//main.js 
exports.myExport = function () {
console.log("This is an example of a named export");
};
exports.anotherExport = function () {
console.log("This is another example of a named export");
};

No bloco de código acima, você está exportando duas funções nomeadas ( minhaExportação e outroExportar ) anexando-os ao exportações objeto.

Da mesma forma, você pode exportar as funções assim:

const myExport = function () { 
console.log("This is an example of a named export");
};
const anotherExport = function () {
console.log("This is another example of a named export");
};
module.exports = {
myExport,
anotherExport,
};

No bloco de código acima, você define o exportações objeto para as funções nomeadas. Você só pode atribuir o exportações objeto para um novo objeto através do módulo objeto.

Seu código geraria um erro se você tentasse fazer desta forma:

//wrong way 
exports = {
myExport,
anotherExport,
};

Há duas maneiras de importar exportações nomeadas:

1. Importe todas as exportações como um único objeto e acesse-as separadamente usando a notação de ponto .

Por exemplo:

//otherModule.js 
const foo = require("./main");
foo.myExport();
foo.anotherExport();

2. Desestruturar as exportações do exportações objeto.

Por exemplo:

//otherModule.js 
const { myExport, anotherExport } = require("./main");
myExport();
anotherExport();

Uma coisa é comum em todos os métodos de importação, eles devem ser importados usando os mesmos nomes com os quais foram exportados.

Exportações padrão

Uma exportação padrão é uma exportação identificada por qualquer nome de sua escolha. Você só pode ter uma exportação padrão por módulo.

Por exemplo:

//main.js 
class Foo {
bar() {
console.log("This is an example of a default export");
}
}
module.exports = Foo;

No bloco de código acima, você está exportando uma classe ( Foo ) reatribuindo o exportações objetar a isso.

A importação de exportações padrão é semelhante à importação de exportações nomeadas, exceto que você pode usar qualquer nome de sua escolha para importá-las.

Por exemplo:

//otherModule.js 
const Bar = require("./main");
const object = new Bar();
object.bar();

No bloco de código acima, a exportação padrão foi nomeada Bar , embora você possa usar qualquer nome de sua escolha.

O Sistema de Módulo ES6

O sistema de módulos ECMAScript Harmony, popularmente conhecido como módulos ES6, é o sistema oficial de módulos JavaScript.

Os módulos ES6 são suportados por navegadores e servidores, embora seja necessário um pouco de configuração antes de usá-los.

Nos navegadores, você deve especificar o modelo Como módulo na tag de importação de script.

Igual a:

//index.html 
<script src="./app.js" type="module"></script>

No Node.js, você precisa definir modelo para módulo na tua pacote.json Arquivo.

Igual a:

//package.json 
"type":"module"

Você também pode exportar variáveis ​​usando o sistema de módulos ES6 usando exportações nomeadas ou exportações padrão.

Exportações nomeadas

Semelhante às importações nomeadas em módulos CommonJS, elas são identificadas pelos nomes aos quais foram atribuídas e permitem várias exportações por módulo.

Por exemplo:

como faço para reiniciar meu macbook pro
//main.js 
export const myExport = function () {
console.log("This is an example of a named export");
};
export const anotherExport = function () {
console.log("This is another example of a named export");
};

No sistema do módulo ES6, as exportações nomeadas são exportadas prefixando a variável com o exportar palavra-chave.

As exportações nomeadas podem ser importadas para outro módulo no ES6 da mesma forma que o CommonJS:

  • Desestruturando as exportações necessárias do exportações objeto.
  • Importando todas as exportações como um único objeto e acessando-as separadamente usando a notação de ponto.

Veja um exemplo de desestruturação:

//otherModule.js 
import { myExport, anotherExport } from "./main.js";
myExport()
anotherExport()

Aqui está um exemplo de importação de todo o objeto:

import * as foo from './main.js' 
foo.myExport()
foo.anotherExport()

No bloco de código acima, o asterisco ( * ) significa “todos”. o Como palavra-chave atribui a exportações objeto para a string que o segue, neste caso, foo .

Exportações padrão

Semelhante às exportações padrão no CommonJS, elas são identificadas por qualquer nome de sua escolha e você só pode ter uma exportação padrão por módulo.

Por exemplo:

//main.js 
class Foo {
bar() {
console.log("This is an example of a default export");
}
}
export default Foo;

As exportações padrão são criadas adicionando o predefinição palavra-chave após o exportar palavra-chave, seguida pelo nome da exportação.

A importação de exportações padrão é semelhante à importação de exportações nomeadas, exceto que você pode usar qualquer nome de sua escolha para importá-las.

Por exemplo:

//otherModule.js 
import Bar from "./main.js";

Exportações mistas

O padrão do módulo ES6 permite que você tenha exportações padrão e exportações nomeadas em um módulo, ao contrário do CommonJS.

Por exemplo:

//main.js 
export const myExport = function () {
console.log("This is another example of a named export");
};
class Foo {
bar() {
console.log("This is an example of a default export");
}
}
export default Foo;

Importância dos Módulos

Dividir seu código em módulos não apenas os torna mais fáceis de ler, mas também o torna mais reutilizável e de fácil manutenção. Módulos em JavaScript também tornam seu código menos propenso a erros, pois todos os módulos são executados no modo estrito por padrão.