Existuje v jazyku JavaScript niečo podobné ako @import
v jazyku CSS, čo vám umožňuje zahrnúť súbor JavaScript do iného súboru JavaScript?
Staré verzie JavaScriptu nemali import, include ani require, preto bolo vyvinutých mnoho rôznych prístupov k tomuto problému. Od roku 2015 (ES6) má však JavaScript štandard ES6 modules na import modulov v Node.js, ktorý podporuje aj väčšina moderných prehliadačov. Na zabezpečenie kompatibility so staršími prehliadačmi možno použiť nástroje build a/alebo transpilation.
Moduly ECMAScript (ES6) sú v Node.js podporované od verzie 8.5 s príznakom --experimental-modules
. Všetky príslušné súbory musia mať príponu .mjs
.
// module.mjs
export function hello() {
return "Hello";
}
// main.mjs
import { hello } from 'module'; // or './module'
let val = hello(); // val is "Hello";
Prehliadače majú podporu pre priame načítanie modulov ECMAScript (bez potreby nástrojov ako Webpack) od Safari 10.1, Chrome 61, Firefox 60 a Edge 16. Aktuálnu podporu nájdete na stránke 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);
}
Viac informácií nájdete na adrese https://jakearchibald.com/2017/es-modules-in-browsers/
Dynamické importy umožňujú skriptom načítať iné skripty podľa potreby:
<script type="module">
import('hello.mjs').then(module => {
module.hello('world');
});
</script>
Viac na https://developers.google.com/web/updates/2017/11/dynamic-import
Starý štýl importovania modulov, ktorý sa v Node.js stále hojne používa, je systém module.exports/require.
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"
Existujú aj iné spôsoby, ako v prehliadačoch zahrnúť externý obsah JavaScriptu, ktoré nevyžadujú predspracovanie.
Pomocou volania AJAX môžete načítať ďalší skript a potom ho pomocou eval
spustiť. Toto je najjednoduchší spôsob, ale je obmedzený na vašu doménu kvôli bezpečnostnému modelu sandboxu JavaScriptu. Použitie eval
tiež otvára dvere chybám, hackom a bezpečnostným problémom.
Podobne ako pri dynamických importoch môžete načítať jeden alebo viac skriptov pomocou volania fetch
s použitím sľubov na riadenie poradia vykonávania závislostí skriptov pomocou knižnice 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)}`)
})
Knižnica jQuery poskytuje funkciu načítania v jednom riadku:
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
Do HTML môžete pridať značku skriptu s adresou URL skriptu. Ak sa chcete vyhnúť réžii jQuery, je to ideálne riešenie.
Skript sa dokonca môže nachádzať na inom serveri. Okrem toho prehliadač vyhodnocuje kód. Značku <script>
možno vložiť buď do webovej stránky <head>
, alebo ju vložiť tesne pred uzatváraciu značku </body>
.
Tu je príklad, ako by to mohlo fungovať:
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)
}
Táto funkcia pridá na koniec časti head stránky nový tag <script>
, ktorého atribút src
je nastavený na adresu URL, ktorá je funkcii zadaná ako prvý parameter.
Obe tieto riešenia sú rozobrané a znázornené v článku JavaScript Madness: Dynamic Script Loading.
Teraz je tu veľký problém, o ktorom musíte vedieť. Ak to urobíte, znamená to, že načítate kód na diaľku. Moderné webové prehliadače načítajú súbor a pokračujú vo vykonávaní vášho aktuálneho skriptu, pretože v záujme zvýšenia výkonu načítavajú všetko asynchrónne. (To platí pre metódu jQuery aj pre metódu ručného dynamického načítania skriptu).
Znamená to, že ak použijete tieto triky priamo, nebudete môcť použiť novo načítaný kód nasledujúci riadok po tom, ako ste požiadali o jeho načítanie, pretože sa bude stále načítavať.
Napríklad: my_lovely_script.js
obsahuje 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
Potom stránku znovu načítate stlačením F5. A funguje to! Mätúce... Takže čo s tým ? No, môžete použiť hack, ktorý autor navrhuje v odkaze, ktorý som vám dal. Stručne povedané, pre ľudí, ktorí sa ponáhľajú, používa udalosť na spustenie funkcie spätného volania pri načítaní skriptu. Takže všetok kód využívajúci vzdialenú knižnicu môžete umiestniť do funkcie spätného volania. Napríklad:
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);
}
Potom kód, ktorý chcete použiť PO načítaní skriptu, napíšete do funkcie lambda:
var myPrettyCode = function() {
// Here, do whatever you want
};
Potom to všetko spustíte:
loadScript("my_lovely_script.js", myPrettyCode);
Všimnite si, že skript sa môže vykonať po načítaní DOM alebo pred ním, v závislosti od prehliadača a od toho, či ste zahrnuli riadok script.async = false;
. Je tu skvelý článok o načítavaní Javascriptu vo všeobecnosti, ktorý to rozoberá.
Ako bolo spomenuté na začiatku tejto odpovede, mnohí vývojári používajú vo svojich projektoch nástroje na zostavovanie/transpiláciu, ako sú Parcel, Webpack alebo Babel, ktoré im umožňujú používať nadchádzajúcu syntax JavaScriptu, zabezpečujú spätnú kompatibilitu pre staršie prehliadače, spájajú súbory, minifikujú, vykonávajú delenie kódu atď.
Je možné dynamicky generovať značku JavaScriptu a pripojiť ju k dokumentu HTML zvnútra iného kódu JavaScriptu. Tým sa načíta cielený súbor JavaScript.
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");
Možno môžete použiť túto funkciu, ktorú som našiel na tejto stránke Ako zaradiť súbor JavaScript do súboru 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)
}