Vamos começar este artigo com uma pergunta. O módulo ES2015 increment
contém o seguinte código:
let counter = 0;
counter++;
export default counter;
Em outro módulo, que chamaremos consumer
, o módulo acima é importado 2 vezes:
import counter1 from './increment';
import counter2 from './increment';
counter1;
counter2;
E agora, na verdade, uma pergunta. O que entra nas variáveis counter1
e counter2
depois do módulo consumer
? Para responder a essa pergunta, você precisa entender como o JavaScript executa os módulos e como eles são importados.
Execução do módulo
Para entender como os mecanismos internos do JavaScript funcionam, é útil examinar a especificação .De acordo com a especificação, cada módulo JavaScript está associado a uma entidade de Registro de módulo . Esta entrada possui um método Evaluate()
que o módulo executa:Se este módulo já foi executado com sucesso, retorne indefinido; [...] Caso contrário, execute transitivamente todas as dependências deste módulo e, em seguida, execute este módulo.Como resultado, verifica-se que o mesmo módulo é executado apenas uma vez.Infelizmente, o que você precisa saber para responder à nossa pergunta não se limita a isso. Como garantir que a chamada de instruçãoimport
usando os mesmos caminhos retornará o mesmo módulo?Permitir comandos de importação
A operação abstrata HostResolveImportedModule () é responsável por associar o caminho ao módulo (especificador) com um módulo específico . O código de importação do módulo é assim:import module from 'path';
Aqui está o que a especificação diz sobre isso:Uma implementação do HostResolveImportedModule deve atender aos seguintes requisitos:- O valor normal de retorno deve ser uma instância de uma subclasse específica de Module Record.
- Se a entidade Record do módulo correspondente ao par que faz referência ao ScriptOrModule, o especificador não existir, ou tal entidade não puder ser criada, uma exceção será lançada.
- Cada vez que essa operação é chamada transmitindo a ela como argumentos um par específico de especificadorScriptOrModule, referenciador, no caso de sua execução usual, retorne a mesma instância da entidade Record do Módulo.
Agora considere isso de uma maneira mais compreensível.HostResolveImportedModule(referencingScriptOrModule, specifier)
- uma operação de resumo que retorna do módulo correspondente a um par de parâmetros referencingScriptOrModule
, specifier
:- O parâmetro
referencingScriptOrModule
é o módulo atual, ou seja, o módulo que importa. - Um parâmetro
specifier
é uma string que corresponde ao caminho do módulo na instrução import
.
No final da descrição, HostResolveImportedModule()
diz-se que, ao importar módulos que correspondem ao mesmo caminho, o mesmo módulo é importado:import moduleA from 'path';
import moduleB from 'path';
import moduleC from 'path';
moduleA === moduleB;
moduleB === moduleC;
Curiosamente, a especificação indica que o host (navegador, ambiente Node.js, em geral - qualquer coisa que tente executar o código JavaScript) deve fornecer uma implementação específica HostResolveImportedModule()
.Responda
Após uma leitura cuidadosa da especificação, fica claro que os módulos JavaScript são executados apenas uma vez durante a importação. E ao importar um módulo usando o mesmo caminho, a mesma instância do módulo é retornada.Vamos voltar à nossa pergunta.Um módulo é increment
sempre executado apenas uma vez:
let counter = 0;
counter++;
export default counter;
Independentemente de quantas vezes um módulo foi importado increment
, uma expressão é counter++
avaliada apenas uma vez. Uma variável counter
exportada usando o mecanismo de exportação padrão é importante 1
.Agora dê uma olhada no módulo consumer
:
import counter1 from './increment';
import counter2 from './increment';
counter1;
counter2;
Os comandos import counter1 from './increment'
e import counter2 from './increment'
usam o mesmo caminho - './increment'
. Como resultado, verifica-se que a mesma instância do módulo é importada.Acontece que o mesmo valor 1 é gravado nas variáveis counter1
e counter2
em consumer
.Sumário
Depois de examinar uma pergunta simples, pudemos descobrir mais sobre como os módulos JavaScript são executados e importados.As regras usadas na importação de módulos são bastante simples: o mesmo módulo é executado apenas uma vez. Em outras palavras, o que está no escopo do nível do módulo é executado apenas uma vez. Se um módulo que já foi executado uma vez for importado novamente, ele não será executado novamente. Ao importar um módulo, ele usa o que foi obtido como resultado de uma sessão anterior para descobrir exatamente o que ele exporta.Se um módulo for importado várias vezes, mas o especificador do módulo (caminho para ele) permanecer o mesmo, a especificação JavaScript garantirá que a mesma instância do módulo seja importada.Queridos leitores! Com que frequência você recorre à leitura da especificação JavaScript, descobrindo os recursos do funcionamento de certas construções de linguagem?