Para que possamos entender como os módulos funcionam, considere como exemplo uma calculadora simples, onde criamos dois arquivos. O primeiro, util.mjs armazena e exporta algumas funções que podem ser re-utilizadas em diversos locais do projeto e tem o seguinte conteúdo:
/**
* resultado aproximado de uma circunferência de diâmetro igual a 20.000
*
* @type
*/
export const PI = Math.PI // 3.141592653589793
/**
* recebe por parâmetro uma quantidade indefinida de números e efetua a soma dos
* mesmos.
*
* @param {number[]} params
* @returns valor soma dos parâmetros
*/
export function soma (...params) {
return params.reduce((a, b) => a + b, 0)
}
Perceba no código acima o uso da palavra export precedendo a constante PI e a função soma. Isso significa que ambos os itens podem ser acessados de fora de seus escopos (arquivo), desde que tenham sido importados.
Para fazer a importação utilizamos o segundo arquivo da nossa calculadora,o index.mjs, que é o ponto de partida da nossa aplicação. Vamos importar do arquivo util.mjs a função soma assim como vemos no código abaixo:
import { soma } from './util.mjs'
console.log(soma(10, 20, 30))
// 60
Na linha 1 utilizamos a palavra reservada import, e em chaves o nome da função que será importada, no caso, soma. Por fim, é utilizada a palavra from onde informamos o nome do pacote (no caso do Node.js) ou do arquivo.
É importante lembrar que todas as funções, classes, constantes, etc. são importados como constantes.
Arquivos mjs são arquivos JavaScript com suporte a módulos, ou seja, facilitam a distinção entre arquivos tradicionais e com suporte a módulos.
Sintaxe
No arquivo no qual declaramos o recurso que desejamos compartilhar usamos a instrução export.
export [o-que-queremos-compartilhar]
Agora, no arquivo em que desejamos utilizar o recurso compartilhado usamos a instrução import:
import [o-que-queremos-importar] from [nome-do-modulo]
Na prática
Exemplo 1
Podemos definir um item do módulo como default, ou seja, quando utilizarmos o import sem utilizar chaves estaremos recuperando este item, por exemplo:
export default const soma = (...params) => params.reduce((a, b) => a + b, 0)
Perceba que neste exemplo utilizamos o prefixo default após a palavra import, significando que este item é o padrão do pacote. É importante lembrar que apenas um único item pode ser exportado como default.
Abaixo vemos como acessar um item definido como default:
import sum from 'pacote'
Perceba que a palavra sum não está entre chaves. Além disso, é possível definir qualquer nome para o item porque como default ele não é exportado com um nome.
Exemplo 2
No exemplo a seguir importamos um único item do escopo de outro arquivo. Perceba que dentro das chaves é definido apenas o nome da função que será utilizada:
import { soma } from './util.mjs'
Exemplo 3
Podemos também importar uma quantidade indefinida de itens com o import. Para isso basta utilizar chaves e o nome dos itens separados por virgula, como vemos abaixo:
import { soma, PI } from './util.mjs'
Exemplo 4
Podemos importar junto com o default os itens nomeados que exportamos. Para isso basta fazer como no exemplo abaixo:
import sum, { soma, PI } from './util.mjs'
Exemplo 5
É possível definir um apelido para um item importado, o que podemos ver melhor no exemplo abaixo:
import { soma as somaDeTodosOsValores } from './util.mjs'
É importante lembrar que esta sintaxe só funciona nos itens entre as chaves, como no exemplo, soma e PI.
Exemplo 6
Podemos também importar de um arquivo JavaScript sem trazer nenhum item de seu escopo. Essa prática é comum quando precisamos que um script seja executado sem poluir o escopo atual, funcionando como se estivesse sendo executado em segundo plano:
import './outroScript.mjs'
Exemplo 7
É comum a necessidade de importar todos os itens em um pacote. Para isso os módulos contam com a seguinte sintaxe:
import * as utils from './util.mjs'
console.log(utils)
// { soma, PI }
É importante lembrar que neste tipo de importação o default não é retornado junto com o resto do pacote.
Como testar os módulos no navegador?
Para utilizar na maioria dos navegadores web, basta criar um arquivo HTML e um outro com formato .mjs. Isso significa que é um arquivo JavaScript e suporta os módulos. Em seguida, no JavaScript crie uma tag script, lembrando de informar o nome do seu arquivo mjs no src e o atributo type com o valor module, como podemos ver abaixo:
A partir deste momento, enquanto estiver em um navegador que dê suporte ao recurso será possível utilizar a sintaxe de módulos.
Compatibilidade
Engine | Versão Minima |
---|---|
Node.JS ( V8) | 6.4.0 |
Safari ( WebKit) | 11.1 |
Chrome ( V8) | 68 |
Microsoft Edge ( ChakraCore) | 17 |
Firefox ( Gecko) | 61 |
Nota: O Opera utiliza atualmente grande parte do código do Chrome como base para o seu próprio desenvolvimento e por isso ele não é mencionado nesta listagem.