Resumo : Neste tutorial, você aprenderá sobre a importação dinâmica de JavaScript e como usá-la para importar módulos dinamicamente.
Introdução à importação dinâmica de JavaScript
ES6 introduziu o conceito de módulo que permite desenvolver código JavaScript modular. Vamos começar com um exemplo simples para entender como funciona a importação dinâmica de JavaScript.
Suponha que temos um projeto com a seguinte estrutura:
├── index.html
└── js
├── app.js
└── greeting.js
Linguagem de código: texto simples ( texto simples )
O index.html
carrega o app.js
arquivo do js
diretório. Contém index.html
um botão e exibe um alerta se o botão for clicado:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript Dynamic Import</title>
</head>
<body>
<input type="button" value="Click Me" class="btn">
<script src="js/app.js" type="module"></script>
</body>
</html>
Linguagem de código: HTML, XML ( xml )
O greeting.js
módulo define uma sayHi()
função e a exporta usando uma exportação nomeada:
export function sayHi() {
alert('Hi');
}
Linguagem de código: JavaScript ( javascript )
O app.js
módulo importa a sayHi
função do greeting.js
módulo. Ele seleciona o botão com a classe .btn
e chama a sayHi()
função quando o botão é clicado:
import sayHi from './greeting.js';
const btn = document.querySelector('.btn');
btn.addEventListener('click', () => {
sayHi();
});
Linguagem de código: JavaScript ( javascript )
Antes do ES2020, não era possível carregar o greeting.js
módulo dinamicamente quando necessário.
Por exemplo, o app.js
módulo a seguir tenta carregar o greeting.js
módulo somente quando o botão é clicado e causa um erro:
const btn = document.querySelector('.btn');
btn.addEventListener('click', () => {
import sayHi from './greeting.js'; // ERROR
sayHi();
});
Linguagem de código: JavaScript ( javascript )
ES2020 introduziu a importação dinâmica do módulo por meio de função import()
com a seguinte sintaxe:
import(moduleSpecifier);
Linguagem de código: JavaScript ( javascript )
O import()
permite importar dinamicamente um módulo quando necessário.
Veja como import()
funciona:
- O
import()
aceita um especificador de módulo (moduleSpecifier
) que tem o mesmo formato que o especificador de módulo usado para aimport
instrução. Além disso,moduleSpecifier
pode ser uma expressão avaliada como uma string. - O
import()
retorno aPromise
que será cumprido assim que o módulo for completamente carregado.
A seguir ilustra como carregar o greeting.js
módulo dinamicamente do módulo app.js usando a import()
sintaxe:
const btn = document.querySelector('.btn');
btn.addEventListener('click', () => {
import('./greeting.js')
.then((greeting) => {
greeting.sayHi();
})
.catch((error) => {
console.error(error);
});
});
Linguagem de código: JavaScript ( javascript )
Como import()
retorna um Promise , você pode usar async/await no app.js
módulo assim:
const btn = document.querySelector('.btn');
btn.addEventListener('click', async () => {
try {
let greeting = await import('./greeting.js');
greeting.sayHi();
} catch (error) {
console.log(error);
}
});
Linguagem de código: JavaScript ( javascript )
Alguns casos de uso prático de importação de JavaScript()
O import()
tem os seguintes casos de uso prático:
1) Carregando módulo sob demanda
Alguns módulos podem não precisar estar disponíveis quando o aplicativo for iniciado. Para melhorar o tempo de carregamento, você pode colocar essa funcionalidade em módulos e usar o import()
para carregá-los sob demanda assim:
function eventHandler() {
import('./module1.js')
.then((ns) => {
// use the module
ns.func();
})
.catch((error) => {
// handle error
});
}
Linguagem de código: JavaScript ( javascript )
2) Carregando módulos com base nas condições
Ao colocar import()
dentro da instrução condicional, como if-else , você pode carregar módulos com base em uma condição específica.
O exemplo a seguir carrega um módulo direcionado a uma plataforma específica:
if( isSpecificPlatform() ) {
import('./platform.js')
.then((ns) => {
ns=>f();
});
}
Linguagem de código: JavaScript ( javascript )
3) Especificadores de módulos computados
O especificador de módulo é uma expressão que permite decidir qual módulo carregar em tempo de execução.
Por exemplo, você pode carregar um módulo baseado na localidade do usuário para mostrar a mensagem no idioma específico do usuário:
let lang = `message_${getUserLocale()}.js`;
import(lang)
.then(...);
Linguagem de código: JavaScript ( javascript )
Mais sobre a importação()
Usando desestruturação de objetos
Se um módulo tiver múltiplas exportações nomeadas, você poderá usar a desestruturação de objetos para receber os objetos de exportação. Suponha que o greeting.js
tenha duas funções:
export function sayHi() {
alert('Hi');
}
export function bye() {
alert('Bye');
}
Linguagem de código: JavaScript ( javascript )
No app.js
, você pode usar a desestruturação de objetos da seguinte maneira:
const btn = document.querySelector('.btn');
btn.addEventListener('click', async () => {
try {
let { sayHi, bye } = await import('./greeting.js');
sayHi();
bye();
} catch (error) {
console.log(error);
}
});
Linguagem de código: JavaScript ( javascript )
Carregando dinamicamente vários módulos
Para carregar vários módulos dinamicamente, você pode usar o Promise.all()
método:
Promise.all([
import(module1),
import(module2),
...])
.then(([module1,module2,module3]) => {
// use the modules
});
Linguagem de código: JavaScript ( javascript )
Acessando a exportação padrão
Se um módulo tiver uma exportação padrão, você poderá acessá-lo usando uma default
palavra-chave como esta:
import(moduleSpecifier)
.then((module) => {
// access the default export
console.log(module.default);
});
Linguagem de código: JavaScript ( javascript )
Por exemplo, podemos alterar a exportação nomeada para exportação padrão:
export default function sayHi() {
alert('Hi');
}
Linguagem de código: JavaScript ( javascript )
No arquivo app.js, podemos importar a função sayHi usando um especificador de módulo e chamar a função sayHi() usando a palavra-chave padrão:
const btn = document.querySelector('.btn');
btn.addEventListener('click', async () => {
try {
let greeting = await import('./greeting.js');
greeting.default();
} catch (error) {
console.log(error);
}
});
Linguagem de código: JavaScript ( javascript )
Resumo
- Use JavaScript
import()
para carregar um módulo dinamicamente. - O
import()
retorno aPromise
que será cumprido assim que o módulo for completamente carregado. - Use o
async
/await
para lidar com o resultado doimport()
. - Use o
Promise.all()
método para carregar vários módulos de uma vez. - Utilize a desestruturação de objetos para atribuir variáveis aos objetos de exportação de um módulo.
- Use a
default
palavra-chave para acessar a exportação padrão.