Aprenda a usar as instruções de exportação e importação
Parece haver alguma confusão quando se trata de módulos JavaScript e como eles funcionam exatamente, e por que existem diferentes formas nas quais podemos usá-los. Hoje vou explicar as diferentes maneiras pelas quais você pode exportar e importar módulos.
Alguma experiência nos módulos JavaScript
Os programas JavaScript começaram como scripts ou aplicativos simples, com bases de código bastante pequenas, mas à medida que evoluíram e, portanto, seus usos aumentaram o tamanho das bases de código aumentaram drasticamente. Para suportar esse aumento, o idioma necessário para suportar um mecanismo sob o qual foi possível separar ou dividir o código em unidades menores e reutilizáveis. O Node.JS teve essa capacidade por um tempo antes de ser incorporado no JavaScript com um recurso chamado modules. E assim, finalmente, eles chegaram ao próprio idioma e aos navegadores.
Por definição, um módulo é apenas um arquivo que pode ser importado de outros módulos (ou arquivos) através da ajuda de diretivas como export
e import
:
export
: palavra-chave rotula variáveis e funções que devem ser acessíveis fora do módulo atual.import
: permite a importação de funcionalidades de outros módulos.
Voltaremos a mais disso depois.
Apresentando um exemplo
Para demonstrar o uso de módulos, criaremos um user
módulo simples que exporá uma User
classe. Vamos revisar a estrutura básica do projeto:
index.html
scripts/
index.js
modules/
user.js
Nosso aplicativo será muito simples e mostrará apenas o nome de um usuário na tela, mas a parte interessante é que o nome virá de uma instância de objeto da User
classe. Vamos vê-lo em ação com uma demonstração ao vivo:
Vamos ver em detalhes o que está acontecendo por partes
Usuário do módulo de exportação
A primeira coisa que precisamos fazer para acessar a User
classe é exportá-la do módulo. Para isso, fazemos uso da export
declaração.
A instrução de exportação é usada ao criar módulos JavaScript para exportar ligações ativas para funções, objetos ou valores primitivos do módulo, para que possam ser usados por outros programas com a instrução de importação.
Vamos ver isso em nosso código:
// file: scripts/modules/user.js
export class User {
constructor(name) {
this.name = name;
}
}
Agora que o módulo foi exportado, podemos usá-lo em outros módulos importando-o.
Importando usuário do módulo
A instrução de importação estática é usada para importar ligações ativas somente leitura que são exportadas por outro módulo. Os módulos importados estão no modo estrito, independentemente de você ser declarado como tal ou não. A instrução de importação não pode ser usada em scripts incorporados, a menos que esse script tenha um tipo = “módulo”. As ligações importadas são chamadas de ligações ativas porque são atualizadas pelo módulo que exportou a ligação.
Vamos ver no nosso exemplo
//file: scripts/index.js
import { User } from './modules/user.js'
const user = new User('Juan')
document.getElementById('user-name').innerText = user.name;
A import
instrução nos permite importar ligações específicas de um módulo. Existem várias maneiras diferentes de especificar o que estamos importando, e iremos discuti-las mais adiante neste post. Por enquanto, em nosso exemplo, estamos apenas importando User
do módulo (ou arquivo) especificado.
Após a importação, podemos usar esse objeto, pois faz parte do mesmo arquivo.
Exportações padrão versus exportações nomeadas
Até agora, exportamos uma classe pelo nome, mas existem 2 maneiras diferentes de exportar para fora dos módulos
- Exportações nomeadas (zero ou mais exportações por módulo)
- Exportações padrão (apenas uma por módulo)
Aqui estão alguns exemplos de exportações nomeadas:
// export features declared earlier
export { myFunction, myVariable };
// export individual features (can export var, let, const, function, class)
export let myVariable = Math.sqrt(2);
export function myFunction() { ... };
Exportações padrão:
// export feature declared earlier as default
export { myFunction as default };
// export individual features as default
export default function () { ... }
export default class { .. }
Exportações nomeadas são úteis para exportar vários valores. Durante a importação, é obrigatório usar o mesmo nome que o objeto correspondente. Mas uma exportação padrão pode ser importada com qualquer nome, por exemplo:
// file: myk.js
const k = 12
export default k
// file: main.js
import m from './myk'
console.log(m)
Ao usar exportações nomeadas, também é possível atribuir um nome personalizado ao valor exportado, como no exemplo a seguir:
const name = 'value'
export {
name as newName
}
O valor exportado pode agora ser importados como newName
em vez de name
.
Importação
Já vimos alguns exemplos de como podemos importar exportações nomeadas ou padrão dos módulos. Mas aqui estão mais opções quando se trata de importação.
Importando uma exportação padrão
import something from 'mymodule'
console.log(something)
Importando uma exportação nomeada
import { var1, var2 } from 'mymodule'
console.log(var1)
console.log(var2)
Renomeando uma importação
import { var1 as myvar, var2 } from 'mymodule'
// Now myvar will be available instead of var1
console.log(myvar)
console.log(var2)
Importando tudo de um módulo
import * as anyName from 'mymodule'
console.log(anyName.var1)
console.log(anyName.var2)
console.log(anyName.default)
Até agora, todas as maneiras que descrevemos aqui são importações estáticas, o que significa que você as coloca em cima do seu arquivo e o conteúdo do módulo é sempre importado. Mas não precisa ser o caso, você também pode ter importações dinâmicas.
Importações dinâmicas
Isso permite que você carregue módulos dinamicamente somente quando eles forem necessários, em vez de precisar carregar tudo antecipadamente. Isso tem algumas vantagens óbvias de desempenho; vamos ler e ver como isso funciona.
Essa nova funcionalidade permite chamar import () como uma função, passando o caminho para o módulo como parâmetro. Ele retorna uma promessa, que cumpre com um objeto de módulo, fornecendo acesso às exportações desse objeto, por exemplo
import('./modules/myModule.js')
.then((module) => {
// Do something with the module.
});
Combinando exportações padrão e nomeadas
Você leu certo! é possível combinar o padrão e o nomeado e, como você pode esperar, pode importar os dois. Vamos ver um exemplo:
//file: mymodule.js
export const named = 'named export'
export function test() {
console.log('exported function')
}
export default 'default export';
E podemos importá-los usando um dos seguintes cenários:
//another file:
import anyName from './mymodule' // where anyName is the default export
// or both named exports
import { named, test } from './mymodule';
// or just one
import { named } from './mymodule';
// or all of them together
import anyName, { named, test } from './mymodule';
Conclusão
Os módulos JavaScript são um recurso poderoso que nos permite organizar melhor nosso código, mas também nos permite compartilhar módulos entre projetos. Espero que tenham gostado e aprendido algo novo hoje.
Obrigado pela leitura!