C'è qualcosa in JavaScript simile a @import
in CSS che ti permette di includere un file JavaScript dentro un altro file JavaScript?
Le vecchie versioni di JavaScript non avevano import, include o require, quindi sono stati sviluppati molti approcci diversi a questo problema. Ma dal 2015 (ES6), JavaScript ha lo standard ES6 modules per importare moduli in Node.js, che è anche supportato dalla maggior parte dei browser moderni. Per la compatibilità con i vecchi browser, si possono usare gli strumenti build e/o transpilation.
I moduli ECMAScript (ES6) sono supportati in Node.js dalla v8.5, con il flag --experimental-modules
. Tutti i file coinvolti devono avere l'estensione .mjs
.
// module.mjs
export function hello() {
return "Hello";
}
// main.mjs
import { hello } from 'module'; // or './module'
let val = hello(); // val is "Hello";
I browser hanno il supporto per caricare i moduli ECMAScript direttamente (non sono richiesti strumenti come Webpack) da Safari 10.1, Chrome 61, Firefox 60, e Edge 16. Controlla il supporto attuale su 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);
}
Leggi di più su https://jakearchibald.com/2017/es-modules-in-browsers/
Le importazioni dinamiche permettono allo script di caricare altri script secondo necessità:
<script type="module">
import('hello.mjs').then(module => {
module.hello('world');
});
</script>
Per saperne di più https://developers.google.com/web/updates/2017/11/dynamic-import
Il vecchio stile di importazione dei moduli, ancora ampiamente usato in Node.js, è il 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"
Ci sono altri modi per JavaScript di includere contenuti JavaScript esterni nei browser che non richiedono una pre-elaborazione.
Si potrebbe caricare uno script aggiuntivo con una chiamata AJAX e poi usare eval
per eseguirlo. Questo è il modo più diretto, ma è limitato al tuo dominio a causa del modello di sicurezza sandbox JavaScript. Usare eval
apre anche la porta a bug, hack e problemi di sicurezza.
Come per le Dynamic Imports è possibile caricare uno o molti script con una chiamata fetch
usando le promesse per controllare l'ordine di esecuzione delle dipendenze degli script utilizzando la libreria 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)}`)
})
La libreria jQuery fornisce funzionalità di caricamento in una riga:
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
Si potrebbe aggiungere un tag script con l'URL dello script nell'HTML. Per evitare l'overhead di jQuery, questa è una soluzione ideale.
Lo script può anche risiedere su un altro server. Inoltre, il browser valuta il codice. Il tag <script>
può essere iniettato sia nella pagina web <head>
, o inserito appena prima del tag di chiusura </body>
.
Ecco un esempio di come potrebbe funzionare:
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)
}
Questa funzione aggiungerà un nuovo tag <script>
alla fine della sezione head della pagina, dove l'attributo src
è impostato all'URL che viene dato alla funzione come primo parametro.
Entrambe queste soluzioni sono discusse e illustrate in JavaScript Madness: Dynamic Script Loading.
Ora, c'è un grosso problema che dovete conoscere. Fare questo implica che si carichi il codice a distanza. I moderni browser web caricheranno il file e continueranno ad eseguire il tuo script corrente perché caricano tutto in modo asincrono per migliorare le prestazioni. (Questo vale sia per il metodo jQuery che per il metodo di caricamento dinamico manuale dello script).
Significa che se usate questi trucchi direttamente, non sarete in grado di usare il vostro codice appena caricato la linea successiva dopo che gli avete chiesto di essere caricato, perché sarà ancora in caricamento.
Per esempio: my_lovely_script.js
contiene 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
Poi ricaricate la pagina premendo F5. E funziona! Confusione... **Allora cosa fare? Beh, puoi usare l'hack che l'autore suggerisce nel link che ti ho dato. In sintesi, per le persone che hanno fretta, lui usa un evento per eseguire una funzione di callback quando lo script viene caricato. Quindi puoi mettere tutto il codice che usa la libreria remota nella funzione di callback. Per esempio:
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);
}
Poi scrivi il codice che vuoi usare DOPO che lo script è stato caricato in una funzione lambda:
var myPrettyCode = function() {
// Here, do whatever you want
};
Poi si esegue il tutto:
loadScript("my_lovely_script.js", myPrettyCode);
Notate che lo script può essere eseguito dopo che il DOM è stato caricato, o prima, a seconda del browser e se avete incluso la linea script.async = false;
. C'è un grande articolo sul caricamento di Javascript in generale che discute questo.
Come menzionato all'inizio di questa risposta, molti sviluppatori usano strumenti di compilazione/traspilazione come Parcel, Webpack o Babel nei loro progetti, consentendo loro di utilizzare la prossima sintassi JavaScript, fornire la compatibilità all'indietro per i vecchi browser, combinare i file, minificare, eseguire la divisione del codice ecc.
È possibile generare dinamicamente un tag JavaScript e aggiungerlo al documento HTML dall'interno di altro codice JavaScript. Questo caricherà un file JavaScript mirato.
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");
Forse puoi usare questa funzione che ho trovato in questa pagina Come includere un file JavaScript in un file 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)
}