Há algo no JavaScript semelhante a @importar
em CSS que permite incluir um arquivo JavaScript dentro de outro arquivo JavaScript?
As versões antigas do JavaScript não tinham importância, incluem, ou requerem, tantas abordagens diferentes para este problema foram desenvolvidas.
Mas desde 2015 (ES6), o JavaScript tem o padrão ES6 módulos para importar módulos no Node.js, que também é suportado por a maioria dos navegadores modernos.
Para compatibilidade com navegadores antigos, ferramentas build e/ou transpilation podem ser usadas.
Os módulos ECMAScript (ES6) são suportados no Node.js desde a v8.5, com a bandeira --experimental-modules'. Todos os arquivos envolvidos devem ter a extensão
.mjs'.
// module.mjs
export function hello() {
return "Hello";
}
// main.mjs
import { hello } from 'module'; // or './module'
let val = hello(); // val is "Hello";
Os navegadores têm tido suporte para carregar módulos ECMAScript diretamente (não são necessárias ferramentas como Webpack) desde Safari 10.1, Chrome 61, Firefox 60, e Edge 16. Verifique o suporte atual em caniuse.
<script type="module">
import { hello } from './hello.mjs';
hello('world');
</script>
// hello.mjs
export function hello(text) {
const div = document.createElement('div');
div.textContent = `Hello ${text}`;
document.body.appendChild(div);
}
Leia mais em https://jakearchibald.com/2017/es-modules-in-browsers/
As importações dinâmicas permitem que o script carregue outros scripts conforme necessário:
<script type="module">
import('hello.mjs').then(module => {
module.hello('world');
});
</script>
Leia mais em https://developers.google.com/web/updates/2017/11/dynamic-import
O antigo estilo de importação de módulos, ainda muito utilizado no Node.js, é o sistema module.exports/require.
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"
Existem outras formas de incluir conteúdos JavaScript externos em navegadores que não requerem pré-processamento.
Você poderia carregar um script adicional com uma chamada AJAX e depois utilizar o eval
para executá-lo. Esta é a forma mais simples, mas é limitada ao seu domínio por causa do modelo de segurança JavaScript sandbox. Utilizar o eval
também abre a porta para bugs, hacks e problemas de segurança.
Como o Dynamic Imports você pode carregar um ou muitos scripts com uma chamada `fetch' utilizando promessas de controle de ordem de execução para dependências de scripts utilizando a biblioteca Fetch Inject:
fetchInject([
'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})
A biblioteca jQuery fornece funcionalidade de carregamento em uma linha:
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
Você poderia 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 tag <script>
pode ser injetada na página web <head>
, ou inserida logo antes da tag de fechamento </body>
.
Aqui está um exemplo de como isto poderia funcionar:
function dynamicallyLoadScript(url) {
var script = document.createElement("script"); // create a script DOM node
script.src = url; // set its src to the provided URL
document.head.appendChild(script); // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
}
Esta função adicionará uma nova tag <script>
ao final da seção do cabeçalho da página, onde o atributo src
é definido para a URL que é dada à função como o primeiro parâmetro.
Ambas as soluções são discutidas e ilustradas em JavaScript Madness: Dynamic Script Loading.
Agora, há um grande problema que você deve saber. Fazendo isso implica que talém carregas remotamente o código. Os navegadores web modernos carregarão o arquivo e continuarão executando seu script atual porque carregam tudo de forma assíncrona para melhorar a performance. (Isto aplica-se tanto ao método jQuery como ao método de carregamento manual de scripts dinâmicos).
Isso significa que se você usar esses truques diretamente, você não será capaz de usar seu código recém-carregado na próxima linha após ter pedido para ser carregado, porque ele ainda estará carregando.
Por exemplo: my_lovely_script.js
contém MySuperObject
:
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
var s = new MySuperObject();
Error : MySuperObject is undefined
Em seguida, você recarrega a página pressionando F5. E funciona! Confuso...
Então o que fazer sobre isso ?
Bem, podes usar o hack que o autor sugere no link que te dei. Em resumo, para pessoas com pressa, ele usa um evento para executar uma função de chamada de retorno quando o script é carregado. Então você pode colocar todo o código usando a biblioteca remota na função de retorno de chamada. Por exemplo:
function loadScript(url, callback)
{
// Adding the script tag to the head as suggested before
var head = document.head;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
Então você escreve o código que deseja usar DEPOIS que o script seja carregado em uma função lambda:
var myPrettyCode = function() {
// Here, do whatever you want
};
Então, você dirige tudo isso:
loadScript("my_lovely_script.js", myPrettyCode);
Note que o script pode ser executado após o DOM ter carregado, ou antes, dependendo do navegador e se você incluiu a linha script.async = false;
. Há um grande artigo sobre carregamento de Javascript em geral que discute isso.
Como mencionado no topo desta resposta, muitos desenvolvedores usam ferramentas de construção/transpilação como Parcel, Webpack ou Babel em seus projetos, permitindo que eles usem a sintaxe JavaScript, forneçam compatibilidade retroativa para navegadores antigos, combinem arquivos, minifiquem, executem divisão de código, etc.
É possível gerar dinamicamente uma tag JavaScript e anexá-la a um documento HTML a partir de dentro de outro código JavaScript. Isto irá carregar um ficheiro JavaScript direccionado.
function includeJs(jsFilePath) {
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
}
includeJs("/path/to/some/file.js");
Talvez você possa usar esta função que eu encontrei nesta página Como posso incluir um arquivo JavaScript em um arquivo JavaScript?:
function include(filename)
{
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = filename;
script.type = 'text/javascript';
head.appendChild(script)
}