Importação dinâmica de JavaScript

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.jsLinguagem de código:  texto simples  ( texto simples )

O index.htmlcarrega o app.jsarquivo do jsdiretório. Contém index.htmlum 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.jsmó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.jsmódulo importa a sayHifunção do greeting.jsmódulo. Ele seleciona o botão com a classe .btne 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.jsmódulo dinamicamente quando necessário.

Por exemplo, o app.jsmódulo a seguir tenta carregar o greeting.jsmó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 a importinstrução. Além disso, moduleSpecifierpode ser uma expressão avaliada como uma string.
  • O import()retorno a Promiseque será cumprido assim que o módulo for completamente carregado.

A seguir ilustra como carregar o greeting.jsmó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.jsmó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.jstenha 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 defaultpalavra-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 a Promiseque será cumprido assim que o módulo for completamente carregado.
  • Use o async/ awaitpara lidar com o resultado do import().
  • 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 defaultpalavra-chave para acessar a exportação padrão.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *