Existe algo em JavaScript semelhante ao @import
CSS que permite incluir um arquivo JavaScript dentro de outro arquivo JavaScript?
javascript
file
import
include
Alec Smart
fonte
fonte
script
tags ordenadas ?Respostas:
As versões antigas do JavaScript não tinham importação, inclusão ou exigência, muitas abordagens diferentes para esse problema foram desenvolvidas.
Mas desde 2015 (ES6), o JavaScript possui o padrão dos módulos ES6 para importar módulos no Node.js., que também é suportado pelos navegadores mais modernos .
Para compatibilidade com navegadores antigos, crie ferramentas como Webpack e Rollup e / ou ferramentas de transpilação como Babel .
Módulos ES6
Os módulos ECMAScript (ES6) são suportados no Node.js. desde a v8.5, com o
--experimental-modules
sinalizador, e desde pelo menos Node.js. v13.8.0, sem o sinalizador. Para ativar "ESM" (vs. sistema de módulos commonjs de estilo anterior Node.js [ "CJS"]) que você quer para uso"type": "module"
empackage.json
ou dar os arquivos a extensão.mjs
. (Da mesma forma, os módulos gravados com o módulo CJS anterior do Node.js. podem ser nomeados.cjs
se o padrão for ESM.)Usando
package.json
:Então
module.js
:Então
main.js
:Usando
.mjs
, você teriamodule.mjs
:Então
main.mjs
:Módulos ECMAScript em navegadores
Os navegadores têm suporte para carregar módulos ECMAScript diretamente (não são necessárias ferramentas como o Webpack) desde o Safari 10.1, Chrome 61, Firefox 60 e Edge 16. Verifique o suporte atual no caniuse . Não há necessidade de usar a
.mjs
extensão do Node.js. Os navegadores ignoram completamente as extensões de arquivo nos módulos / scripts.Leia mais em https://jakearchibald.com/2017/es-modules-in-browsers/
Importações dinâmicas em navegadores
As importações dinâmicas permitem que o script carregue outros scripts conforme necessário:
Leia mais em https://developers.google.com/web/updates/2017/11/dynamic-import
O Node.js requer
O estilo mais antigo do módulo CJS, ainda amplamente usado no Node.js, é o
module.exports
/require
system.Existem outras maneiras de o JavaScript incluir conteúdo externo de JavaScript em navegadores que não requerem pré-processamento.
Carregamento AJAX
Você pode carregar um script adicional com uma chamada AJAX e depois usá
eval
-lo para executá-lo. Essa é a maneira mais direta, mas está limitada ao seu domínio devido ao modelo de segurança da sandbox JavaScript. O usoeval
também abre as portas para bugs, hacks e problemas de segurança.Obter carregamento
Como as importações dinâmicas, você pode carregar um ou vários scripts com uma
fetch
chamada usando promessas para controlar a ordem de execução das dependências de script usando a biblioteca Fetch Inject :Carregamento de jQuery
A biblioteca jQuery fornece a funcionalidade de carregamento em uma linha :
Carregamento de script dinâmico
Você pode adicionar uma tag de script com a URL do script no HTML. Para evitar a sobrecarga do jQuery, esta é uma solução ideal.
O script pode até residir em um servidor diferente. Além disso, o navegador avalia o código. A
<script>
tag pode ser injetada na página da Web<head>
ou inserida imediatamente antes da</body>
tag de fechamento .Aqui está um exemplo de como isso poderia funcionar:
Esta função adicionará uma nova
<script>
tag ao final da seção principal da página, onde osrc
atributo é definido como o URL que é atribuído à função como o primeiro parâmetro.Ambas as soluções são discutidas e ilustradas em JavaScript Madness: Dynamic Script Loading .
Detectando quando o script foi executado
Agora, há um grande problema que você deve conhecer. Isso implica que você carrega remotamente o código . Navegadores modernos carregam o arquivo e continuam executando o script atual, porque carregam tudo de forma assíncrona para melhorar o desempenho. (Isso se aplica ao método jQuery e ao método de carregamento de script dinâmico manual.)
Isso significa que, se você usar esses truques diretamente, não poderá usar o código recém-carregado na próxima linha depois de solicitar que ele seja carregado , porque ainda estará carregando.
Por exemplo:
my_lovely_script.js
contémMySuperObject
:Então você recarrega a página acessando F5. E funciona! Confuso ...
Então o que fazer sobre isso ?
Bem, você pode usar o hack que o autor sugere no link que eu lhe dei. Em resumo, para pessoas com pressa, ele usa um evento para executar uma função de retorno de chamada quando o script é carregado. Assim, você pode colocar todo o código usando a biblioteca remota na função de retorno de chamada. Por exemplo:
Em seguida, você escreve o código que deseja usar APÓS o script ser carregado em uma função lambda :
Então você executa tudo isso:
Observe que o script pode ser executado após o carregamento do DOM, ou antes, dependendo do navegador e se você incluiu a linha
script.async = false;
. Há um ótimo artigo sobre carregamento de Javascript em geral que discute isso.Mesclagem / pré-processamento de código-fonte
Como mencionado na parte superior desta resposta, muitos desenvolvedores usam ferramentas de compilação / transpilação como Parcel, Webpack ou Babel em seus projetos, permitindo que eles usem a próxima sintaxe JavaScript, forneçam compatibilidade com versões anteriores para navegadores antigos, combinem arquivos, minifiquem, executar divisão de código etc.
fonte
onreadystatechange
evento e areadyState
propriedade). Além disso, o carregamento dinâmico de scripts não se beneficia dos scanners de pré-carregamento do Bros. Recomende este artigo do HTML5Rocks: html5rocks.com/en/tutorials/speed/script-loadingSe alguém estiver procurando por algo mais avançado, experimente o RequireJS . Você receberá benefícios adicionais, como gerenciamento de dependência, melhor concorrência e evitará duplicação (ou seja, recuperando um script mais de uma vez).
Você pode gravar seus arquivos JavaScript em "módulos" e referenciá-los como dependências em outros scripts. Ou você pode usar o RequireJS como uma solução simples "vá buscar esse script".
Exemplo:
Defina dependências como módulos:
some-dependency.js
deployment.js é o seu arquivo JavaScript "principal" que depende de some-dependency.js
Trecho do arquivo README do GitHub :
fonte
Na verdade, existe uma maneira de carregar um arquivo JavaScript de forma não assíncrona, para que você possa usar as funções incluídas no seu arquivo recém-carregado logo após carregá-lo, e acho que funciona em todos os navegadores.
Você precisa usar
jQuery.append()
no<head>
elemento da sua página, ou seja:No entanto, esse método também tem um problema: se ocorrer um erro no arquivo JavaScript importado, o Firebug (e também o Firefox Error Console e o Chrome Developer Tools ) informarão seu lugar incorretamente, o que é um grande problema se você usar o Firebug para rastrear Erros de JavaScript caem muito (sim). O Firebug simplesmente não sabe sobre o arquivo recém-carregado por algum motivo; portanto, se ocorrer um erro nesse arquivo, ele informa que ocorreu no seu HTML principal arquivo e você terá problemas para descobrir a verdadeira razão do erro.
Mas se isso não for um problema para você, esse método deve funcionar.
Na verdade, eu escrevi um plugin jQuery chamado $ .import_js () que usa este método:
Portanto, tudo que você precisa fazer para importar o JavaScript é:
Também fiz um teste simples para isso no Exemplo .
Ele inclui um
main.js
arquivo no HTML principal e, em seguida, o script émain.js
usado$.import_js()
para importar um arquivo adicional chamadoincluded.js
, que define esta função:E logo após a inclusão
included.js
, ahello()
função é chamada e você recebe o alerta.(Esta resposta é uma resposta ao comentário do e-satis).
fonte
jQuery.getScript
, dessa forma você não precisa se preocupar em escrever o plugin ...script
elemento aohead
fará com que ele seja executado de forma assíncrona, a menos queasync
esteja definido especificamente comofalse
."
, código vai quebrarOutra maneira, que na minha opinião é muito mais limpa, é fazer uma solicitação síncrona do Ajax em vez de usar uma
<script>
tag. Também é assim que o Node.js lida com inclui.Aqui está um exemplo usando o jQuery:
Em seguida, você pode usá-lo em seu código, como normalmente usaria uma inclusão:
E poder chamar uma função do script necessário na próxima linha:
fonte
async: false
supostamente está obsoleto. Não é! Como sua cotação indica, apenas o material relacionado ao jqXHR é.Há uma boa notícia para você. Em breve, você poderá carregar o código JavaScript facilmente. Ele se tornará uma maneira padrão de importar módulos de código JavaScript e fará parte do próprio JavaScript principal.
Você simplesmente precisa escrever
import cond from 'cond.js';
para carregar uma macro chamadacond
de um arquivocond.js
.Portanto, você não precisa confiar em nenhuma estrutura JavaScript nem precisa fazer explicitamente chamadas para o Ajax .
Referir-se:
Resolução do módulo estático
Carregadores de módulos
fonte
É possível gerar dinamicamente uma tag JavaScript e anexá-la ao documento HTML de outro código JavaScript. Isso carregará o arquivo JavaScript direcionado.
fonte
js.onload = callback;
Declaração
import
está no ECMAScript 6.Sintaxe
fonte
Talvez você possa usar esta função que encontrei nesta página. Como incluo um arquivo JavaScript em um arquivo JavaScript? :
fonte
script.onload = callback;
var
, a variável será global?head
.Aqui está uma versão síncrona sem jQuery :
Observe que, para obter esse domínio entre domínios, o servidor precisará definir o
allow-origin
cabeçalho em sua resposta.fonte
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)<script>
tag inserida , não porXMLHttpRequest
.const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1");
Acabei de escrever este código JavaScript (usando Prototype para manipulação de DOM ):
Uso:
Gist: http://gist.github.com/284442 .
fonte
Aqui está a versão generalizada de como o Facebook faz isso por seu onipresente botão Curtir:
Se funcionar para o Facebook, funcionará para você.
A razão pela qual procuramos o primeiro
script
elemento em vez dehead
oubody
é porque alguns navegadores não criam um se estiverem ausentes, mas garantimos que temos umscript
elemento - este. Leia mais em http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ .fonte
Se você deseja JavaScript puro, pode usar
document.write
.Se você usar a biblioteca jQuery, poderá usar o
$.getScript
métodofonte
Você também pode montar seus scripts usando PHP :
Arquivo
main.js.php
:fonte
A maioria das soluções mostradas aqui implica carregamento dinâmico. Eu estava procurando um compilador que reunisse todos os arquivos dependentes em um único arquivo de saída. O mesmo que os pré-processadores Less / Sass lidam com a
@import
regra geral do CSS . Como não achei nada decente desse tipo, escrevi uma ferramenta simples para resolver o problema.Então, aqui está o compilador, https://github.com/dsheiko/jsic , que substitui
$import("file-path")
com segurança o conteúdo do arquivo solicitado. Aqui está o plug-in Grunt correspondente : https://github.com/dsheiko/grunt-jsic .No ramo mestre do jQuery, eles simplesmente concatenam os arquivos de origem atômica em um único começando
intro.js
e terminando comouttro.js
. Isso não combina comigo, pois não oferece flexibilidade no design do código-fonte. Confira como ele funciona com o jsic:src / main.js
src / Form / Input / Tel.js
Agora podemos executar o compilador:
E obtenha o arquivo combinado
build / main.js
fonte
Se sua intenção de carregar o arquivo JavaScript estiver usando as funções do arquivo importado / incluído , você também poderá definir um objeto global e definir as funções como itens de objeto. Por exemplo:
global.js
file1.js
file2.js
main.js
Você só precisa ter cuidado ao incluir scripts em um arquivo HTML. O pedido deve ser como abaixo:
fonte
Isso deve fazer:
fonte
eval
que há de errado com isso. De Crockford , "eval
é ruim. Aeval
função é o recurso mais mal utilizado do JavaScript. Evite-o.eval
Possui aliases. Não use oFunction
construtor. Não passe as strings parasetTimeout
ousetInterval
". Se você ainda não leu o "JavaScript: The Good Parts", faça o mesmo agora. Você não vai se arrepender.http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)Ou, em vez de incluir no tempo de execução, use um script para concatenar antes do upload.
Eu uso rodas dentadas (não sei se existem outros). Você constrói seu código JavaScript em arquivos separados e inclui comentários que são processados pelo mecanismo Sprockets como inclui. Para o desenvolvimento, você pode incluir arquivos seqüencialmente e, em seguida, para a produção mesclá-los ...
Veja também:
fonte
Eu tinha um problema simples, mas fiquei perplexo com as respostas a essa pergunta.
Eu tive que usar uma variável (myVar1) definida em um arquivo JavaScript (myvariables.js) em outro arquivo JavaScript (main.js).
Para isso, fiz o seguinte:
Carregou o código JavaScript no arquivo HTML, na ordem correta, primeiro myvariables.js, depois main.js:
Arquivo: myvariables.js
Arquivo: main.js
Como você viu, eu usava uma variável em um arquivo JavaScript em outro arquivo JavaScript, mas não precisava incluir uma em outro. Eu só precisava garantir que o primeiro arquivo JavaScript carregado antes do segundo arquivo JavaScript e as variáveis do primeiro arquivo JavaScript estivessem acessíveis no segundo arquivo JavaScript automaticamente.
Isso salvou meu dia. Eu espero que isso ajude.
fonte
import
. Você precisa de um arquivo HTML para obter coisas de um arquivo js para outro.<script>
tag. Isso pode ajudar na organização. Essa resposta simplesmente não é o que a pergunta estava pedindo e não é ideal nesse contexto.Caso você esteja usando Trabalhadores da Web e queira incluir scripts adicionais no escopo do trabalhador, as outras respostas fornecidas sobre a adição de scripts ao
head
tag etc. não funcionarão para você.Felizmente, os Web Workers têm sua própria
importScripts
função, que é uma função global no escopo do Web Worker, nativa do próprio navegador, pois faz parte da especificação .Como alternativa, como destaca a segunda resposta mais votada para sua pergunta , o RequireJS também pode lidar com a inclusão de scripts dentro de um Web Worker (provavelmente se chamando
importScripts
, mas com alguns outros recursos úteis).fonte
Na linguagem moderna, com a verificação se o script já foi carregado, seria:
Uso (assíncrono / aguardar):
ou
Uso (Promessa):
fonte
var pi = 3.14
. chamar a função loadJS () vialoadJs("pi.js").then(function(){ console.log(pi); });
A
@import
sintaxe para obter a importação de JavaScript do tipo CSS é possível usando uma ferramenta como o Mixture por meio de seu.mix
tipo de arquivo especial (veja aqui ). Eu imagino que o aplicativo simplesmente use um dos métodos mencionados acima de forma interativa, embora eu não saiba.Na documentação do Mixture em
.mix
arquivos:Aqui está um
.mix
arquivo de exemplo que combina vários.js
arquivos em um:A mistura produz isso como
scripts-global.js
e também como uma versão minificada (scripts-global.min.js
).Nota: Eu não sou afiliado de maneira alguma ao Mixture, além de usá-lo como uma ferramenta de desenvolvimento front-end. Me deparei com esta questão ao ver um
.mix
arquivo JavaScript em ação (em um dos clichês do Mixture) e ficar um pouco confuso com ele ("você pode fazer isso?", Pensei comigo mesmo). Então percebi que era um tipo de arquivo específico do aplicativo (um pouco decepcionante, concordou). No entanto, percebi que o conhecimento pode ser útil para outras pessoas.ATUALIZAÇÃO : A mistura agora é gratuita (offline).
ATUALIZAÇÃO : A mistura está descontinuada. Versões antigas de mistura ainda estão disponíveis
fonte
fonte
body
ainda não existe ou não pode ser modificado. Além disso, ajuda a explicar as respostas.Meu método usual é:
Ele funciona muito bem e não usa recargas de página para mim. Eu tentei o método AJAX (uma das outras respostas), mas ele não parece funcionar tão bem para mim.
Aqui está uma explicação de como o código funciona para aqueles que são curiosos: essencialmente, ele cria uma nova tag de script (após a primeira) da URL. Ele define o modo assíncrono para não bloquear o restante do código, mas chama um retorno de chamada quando o readyState (o estado do conteúdo a ser carregado) muda para 'carregado'.
fonte
Embora essas respostas sejam ótimas, existe uma "solução" simples que existe desde o carregamento do script, e cobrirá 99,999% dos casos de uso da maioria das pessoas. Basta incluir o script necessário antes do script que o requer. Para a maioria dos projetos, não demora muito para determinar quais scripts são necessários e em que ordem.
Se script2 requer script1, essa é realmente a maneira mais fácil de fazer algo assim. Estou muito surpreso que ninguém tenha levantado isso, pois é a resposta mais óbvia e mais simples que será aplicada em quase todos os casos.
fonte
Escrevi um módulo simples que automatiza o trabalho de importar / incluir scripts de módulo em JavaScript. Para obter uma explicação detalhada do código, consulte a postagem no blog JavaScript require / import / include modules .
fonte
Este script adicionará um arquivo JavaScript ao topo de qualquer outra
<script>
tag:fonte
Há também Head.js . É muito fácil lidar com:
Como você vê, é mais fácil que o Require.js e tão conveniente quanto o
$.getScript
método do jQuery . Ele também possui alguns recursos avançados, como carregamento condicional, detecção de recursos e muito mais .fonte
Existem muitas respostas possíveis para essa pergunta. Minha resposta é obviamente baseada em várias delas. Foi isso que acabei depois de ler todas as respostas.
O problema
$.getScript
e realmente qualquer outra solução que exija retorno de chamada quando o carregamento estiver concluído é que, se você tiver vários arquivos que o utilizam e dependem um do outro, não terá mais como saber quando todos os scripts foram carregados (uma vez aninhados em vários arquivos).Exemplo:
file3.js
file2.js:
file1.js:
Você está certo quando diz que pode especificar o Ajax para executar de forma síncrona ou usar XMLHttpRequest , mas a tendência atual parece ser descontinuar solicitações síncronas, portanto, talvez você não obtenha suporte total ao navegador agora ou no futuro.
Você pode tentar usar
$.when
para verificar uma matriz de objetos adiados, mas agora está fazendo isso em todos os arquivos e o arquivo2 será considerado carregado assim que$.when
não for executado quando o retorno de chamada for executado, portanto, o arquivo1 ainda continuará a execução antes do carregamento do arquivo3 . Isso realmente ainda tem o mesmo problema.Decidi voltar ao invés de avançar. Obrigado
document.writeln
. Eu sei que é um tabu, mas contanto que seja usado corretamente, isso funcionará bem. Você acaba com um código que pode ser depurado facilmente, exibido corretamente no DOM e pode garantir a ordem em que as dependências são carregadas corretamente.Obviamente, você pode usar $ ("body"). Append (), mas não poderá mais depurar corretamente.
NOTA: Você deve usá-lo apenas enquanto a página estiver carregando, caso contrário, você verá uma tela em branco. Em outras palavras, sempre coloque-o antes / fora do documento.ready . Eu não testei usando isso depois que a página foi carregada em um evento de clique ou algo assim, mas tenho certeza que ela falhará.
Gostei da idéia de estender o jQuery, mas obviamente você não precisa.
Antes de chamar
document.writeln
, ele verifica se o script ainda não foi carregado, avaliando todos os elementos do script.Presumo que um script não seja totalmente executado até que seu
document.ready
evento seja executado. (Eu sei que o usodocument.ready
não é obrigatório, mas muitas pessoas o usam, e lidar com isso é uma salvaguarda.)Quando os arquivos adicionais são carregados, os
document.ready
retornos de chamada são executados na ordem errada. Para resolver isso quando um script é realmente carregado, o script que o importou é reimportado e a execução é interrompida. Isso faz com que o arquivo de origem agora tenha seudocument.ready
retorno de chamada executado após qualquer um dos scripts importados.Em vez dessa abordagem, você poderia tentar modificar o jQuery
readyList
, mas essa parecia uma solução pior.Solução:
Uso:
Arquivo3:
Arquivo2:
Arquivo1:
fonte
Existem várias maneiras de implementar módulos em Javascript. Aqui estão as 2 mais populares:
Módulos ES6
Os navegadores ainda não oferecem suporte a esse sistema de modulação. Para usar essa sintaxe, você deve usar um bundler como o webpack. O uso de um bundler é melhor de qualquer maneira, pois isso pode combinar todos os seus arquivos diferentes em um único arquivo (ou em dois). Isso servirá os arquivos do servidor para o cliente mais rapidamente, pois cada solicitação HTTP possui alguma sobrecarga associada. Assim, ao reduzir a solicitação HTTP geral, melhoramos o desempenho. Aqui está um exemplo dos módulos ES6:
CommonJS (usado no NodeJS)
Este sistema de modulação é usado no NodeJS. Você basicamente adiciona suas exportações a um objeto chamado
module.exports
. Você pode acessar esse objeto através de umrequire('modulePath')
. Importante aqui é perceber que esses módulos estão sendo armazenados em cache; portanto, se você tiverrequire()
um determinado módulo duas vezes, ele retornará o módulo já criado.fonte
Cheguei a essa pergunta porque estava procurando uma maneira simples de manter uma coleção de plugins JavaScript úteis. Depois de ver algumas das soluções aqui, eu vim com isso:
Configure um arquivo chamado "plugins.js" (ou extensions.js ou o que você quiser). Mantenha seus arquivos de plug-in junto com esse único arquivo mestre.
plugins.js terá uma matriz chamada na
pluginNames[]
qual iremos iterar eeach()
, em seguida, anexar uma<script>
tag na cabeça de cada plug-in<script src="js/plugins/plugins.js"></script>
MAS:
Embora todos os plugins sejam inseridos na tag head da maneira que deveriam, eles nem sempre são executados pelo navegador quando você clica na página ou atualiza.
Descobri que é mais confiável escrever apenas as tags de script em um PHP include. Você só precisa escrevê-lo uma vez e isso funciona tanto quanto chamar o plugin usando JavaScript.
fonte