Os módulos permitem que blocos de código como funções, classes e constantes em arquivos separados possam ser importados quando necessário, facilitando o processo de manutenção e reusabilidade de um projeto JavaScript.
Antes desse recurso era necessário declarar variáveis globais em arquivos .js que, quando adicionados a mesma página, permitiam que essas variáveis passassem a fazer parte do mesmo contexto. Com os módulos o conteúdo de um arquivo pode ser exportado para outro, assim como fazemos com include/require no PHP, por exemplo.
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]
Como utilizar?
Para entender melhor, 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 {number}
*/
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 {number} 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.
Quais as variações da sintaxe do import?
Existem algumas variações na sintaxe dos módulos, veremos em pequenos exemplos como são estas variações.
1. Importando o conteúdo default
Podemos definir um item do módulo como default, ou seja, quando utilizarmos o import sem utilizar chaves estaremos recuperando este item, por exemplo:
import 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.
2. importando um único item
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'
3. importando vários itens
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'
4. importando o default e outros itens
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'
5. definindo um aliás para um item
É 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.
6. importando apenas o arquivo.
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.js'
7. importando todos os itens de um pacote
É 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 type como module, como podemos ver abaixo:
<script type="module" src="index.mjs"></script>
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) | 8.5.0 |
Safari ( WebKit) | 11.4 |
Chrome ( V8) | 68 |
Microsoft Edge ( ChakraCore) | 17 |
Firefox ( Gecko) | 61 |
- No Node.js os módulos ainda estão em estágio experimental.
Nota: O Opera atualmente é um fork do Google Chrome e, por isso, o mesmo foi desconsiderado da lista. Caso você o utilize, verifique na documentação do mesmo se a versão atual possui suporte ao recurso mencionado aqui. É importante lembrar a versão atual do Chrome não equivale a última versão do Opera.
Saiba mais Veja a Série O JavaScript está dominando o mundo?