Finnes det noe i JavaScript som ligner på @import
i CSS som lar deg inkludere en JavaScript-fil inne i en annen JavaScript-fil?
De gamle versjonene av JavaScript hadde ingen import, inkludering eller krav, så det er utviklet mange forskjellige tilnærminger til dette problemet. Men siden 2015 (ES6) har JavaScript hatt ES6-moduler som standard for å importere moduler i Node.js, som også støttes av de fleste moderne nettlesere. For kompatibilitet med eldre nettlesere kan verktøyene build og/eller transpilation brukes.
ECMAScript-moduler (ES6) har vært støttet i Node.js siden v8.5, med flagget --experimental-modules
. Alle involverte filer må ha filtypen .mjs
.
// module.mjs
export function hello() {
return "Hello";
}
// main.mjs
import { hello } from 'module'; // or './module'
let val = hello(); // val is "Hello";
Nettlesere har hatt støtte for å laste ECMAScript-moduler direkte (ingen verktøy som Webpack kreves) siden Safari 10.1, Chrome 61, Firefox 60 og Edge 16. Sjekk gjeldende støtte på 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);
}
Les mer på https://jakearchibald.com/2017/es-modules-in-browsers/
Dynamisk import lar skriptet laste inn andre skript etter behov:
<script type="module">
import('hello.mjs').then(module => {
module.hello('world');
});
</script>
Les mer på https://developers.google.com/web/updates/2017/11/dynamic-import
Den gamle måten å importere moduler på, som fortsatt er mye brukt i Node.js, er module.exports/require-systemet.
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"
Det finnes andre måter for JavaScript å inkludere eksternt JavaScript-innhold i nettlesere som ikke krever forhåndsbehandling.
Du kan laste inn et ekstra skript med et AJAX-kall og deretter bruke eval
for å kjøre det. Dette er den enkleste måten, men den er begrenset til domenet ditt på grunn av JavaScript-sandkassens sikkerhetsmodell. Bruk av eval
åpner også døren for feil, hacking og sikkerhetsproblemer.
I likhet med Dynamic Imports kan du laste inn ett eller flere skript med et fetch
-kall ved hjelp av løfter for å kontrollere rekkefølgen på utførelsen for skriptavhengigheter ved hjelp av biblioteket 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)}`)
})
Biblioteket jQuery tilbyr lastefunksjonalitet i én linje:
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
Du kan legge til en skript-tag med skriptets URL i HTML-koden. For å unngå overhead av jQuery er dette en ideell løsning.
Skriptet kan til og med ligge på en annen server. Videre evaluerer nettleseren koden. Taggen <script>
kan injiseres i enten nettsidens <head>
eller settes inn like før den avsluttende </body>
-taggen.
Her er et eksempel på hvordan dette kan fungere:
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)
}
Denne funksjonen vil legge til en ny <script>
-tag på slutten av head-delen av siden, der src
-attributtet er satt til URL-adressen som er gitt til funksjonen som første parameter.
Begge disse løsningene er diskutert og illustrert i JavaScript Madness: Dynamic Script Loading.
Nå er det et stort problem du må vite om. Å gjøre det innebærer at du laster inn koden eksternt. Moderne nettlesere vil laste inn filen og fortsette å kjøre det gjeldende skriptet fordi de laster alt asynkront for å forbedre ytelsen. (Dette gjelder både jQuery-metoden og den manuelle dynamiske skriptinnlastingsmetoden).
Det betyr at hvis du bruker disse triksene direkte, vil du ikke kunne bruke den nylig lastede koden din neste linje etter at du ba om at den skulle lastes inn , fordi den fremdeles lastes inn.
For eksempel: my_lovely_script.js
inneholder 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
Deretter laster du inn siden på nytt ved å trykke F5. Og det fungerer! Forvirrende... **Så hva skal jeg gjøre med det? Vel, du kan bruke hacket forfatteren foreslår i lenken jeg ga deg. Oppsummert, for folk som har det travelt, bruker han en hendelse for å kjøre en tilbakeringingsfunksjon når skriptet lastes inn. Så du kan legge all koden ved hjelp av det eksterne biblioteket i tilbakeringingsfunksjonen. For eksempel:
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);
}
Deretter skriver du koden du vil bruke ETTER at skriptet er lastet inn i en lambda-funksjon:
var myPrettyCode = function() {
// Here, do whatever you want
};
Så kjører du alt dette:
loadScript("my_lovely_script.js", myPrettyCode);
Merk at skriptet kan kjøres etter at DOM-en er lastet, eller før, avhengig av nettleseren og om du inkluderte linjen script.async = false;
. Det finnes en flott artikkel om innlasting av Javascript generelt som diskuterer dette.
Som nevnt øverst i dette svaret bruker mange utviklere bygge/transpilasjonsverktøy som Parcel, Webpack eller Babel i sine prosjekter, slik at de kan bruke kommende JavaScript-syntaks, gi bakoverkompatibilitet for eldre nettlesere, kombinere filer, minifisere, utføre kodesplitting osv.
Det er mulig å generere en JavaScript-tag dynamisk og legge den til et HTML-dokument inne i annen JavaScript-kode. Dette vil laste inn målrettet JavaScript-fil.
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");
Kanskje du kan bruke denne funksjonen som jeg fant på denne siden Hvordan inkluderer jeg en JavaScript-fil i en JavaScript-fil?:
function include(filename)
{
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = filename;
script.type = 'text/javascript';
head.appendChild(script)
}