Kako uključiti javascript datoteku u drugi javascript datoteku?

Da li JavaScript ima nešto slično kao @import u CSS-u koji vam omogućuje da uključite javascript datoteku u drugu javascript datoteku?

4465
04 июня '09 в 14:59 2009-06-04 14:59 Alec Smart je postavljen za 4. lipnja u 14:59 2009-06-04 14:59
@ 56 odgovora
  • 1
  • 2

U starijim verzijama JavaScripta nije bilo uvoza, uključivanja ili zahtjeva, tako da je razvijeno mnogo različitih pristupa ovom problemu.

No, od 2015. (ES6) standard ES6 modula za uvoz modula u Node.js pojavio se u JavaScriptu, koji je također podržan od strane većine modernih preglednika .

Za kompatibilnost sa starijim preglednicima možete koristiti alate za izgradnju i / ili prijenos .

Moduli ES6

Moduli ECMAScript (ES6) podržani su u Node.js od verzije - --experimental-modules zastavom - --experimental-modules . Sve .mjs datoteke moraju imati proširenje .mjs .

 // main.mjs import { hello } from 'module'; // or './module' let val = hello(); // val is "Hello"; 

ECMAScript moduli u preglednicima

Preglednici podržavaju izravno učitavanje ECMAScript modula (nisu potrebni nikakvi alati kao što je Webpack) počevši sa Safari 10.1, Chrome 61, Firefox 60 i Edge 16. Provjerite trenutnu podršku u caniuse .

 // hello.mjs export function hello(text) { const div = document.createElement('div'); div.textContent = 'Hello ${text}'; document.body.appendChild(div); } 

Saznajte više na https://jakearchibald.com/2017/es-modules-in-browsers/

Dinamičan uvoz u preglednicima

Dinamički uvoz dopušta skripti da po potrebi učita druge skripte:

https://developers.google.com/web/updates/2017/11/dynamic-import. 

Node.js zahtijeva

Stari stil uvoza modula, koji se još uvijek široko koristi u Node.js, je modul.exports / require .

 // server.js const myModule = require('./mymodule'); let val = myModule.hello(); // val is "Hello" 

Postoje i drugi načini za omogućavanje vanjskog sadržaja JavaScripta u preglednicima koji ne zahtijevaju prethodnu obradu.

AJAX preuzimanje

Dodatnu skriptu možete učitati pomoću AJAX poziva, a zatim pomoću programa eval pokrenuti ga. To je najjednostavniji način, ali je ograničen na vašu domenu zbog JavaScript sigurnosnog modela sigurnosnog okvira. Korištenje programa eval otvara put za bugove, hakiranje i sigurnosna pitanja.

Preuzimanje Preuzimanje

Kao i kod dinamičkog uvoza, možete učitati jednu ili više skripti pozivajući fetch pomoću obećanja za upravljanje redoslijedom kojim se zavisnosti skripta pokreću pomoću knjiž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)}') }) 

JQuery učitavanje

Knjižnica jQuery učitava jedan redak :

 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) } 

Ova funkcija će dodati novi <script> na kraj dijela glave stranice, gdje je atribut src postavljen na URL, koji se prosljeđuje funkciji kao prvi parametar.

Oba ova rješenja se raspravljaju i ilustriraju u JavaScript Madnessu: dinamičko učitavanje skripti .

Otkrivanje kada je skripta izvršena

Sada postoji veliki problem za koji trebate biti svjesni. To znači da kôd preuzimate daljinski. Moderni web-preglednici učitavaju datoteku i nastavljaju izvršavati vašu trenutnu skriptu, jer sve to asinhrono učitavaju kako bi poboljšali performanse. (To se odnosi i na jQuery metodu i na metodu ručnog dinamičkog učitavanja skripte.)

To znači da, ako izravno koristite ove trikove, nećete moći koristiti novonastali kod u sljedećem retku nakon što ga zatražite da ga preuzmete jer će se i dalje učitati.

Na primjer: my_lovely_script.js sadrži MySuperObject :

 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); } 

Zatim pišete kod koji želite koristiti nakon što se skripta učita u lambda funkciju :

 loadScript("my_lovely_script.js", myPrettyCode); 

Imajte na umu da se skripta može izvršiti nakon učitavanja DOM-a ili ranije, ovisno o pregledniku i o tome je li script.async = false; omogućen script.async = false; Postoji veliki članak o preuzimanju Javascripta općenito, o kojem se govori.

Spajanje / predobrada izvornog koda

Kao što je spomenuto na vrhu ovog odgovora, mnogi programeri u svojim projektima koriste alate za izgradnju / prijenos, kao što su Parcel, Webpack ili Babel, što im omogućuje korištenje nadolazeće JavaScript sintakse, osiguravanje kompatibilnosti za starije preglednike, spajanje datoteka, minimiziranje, razdvajanje koda i tako dalje

3838
04 июня '09 в 15:13 2009-06-04 15:13 odgovor je dat e-satis 04 lipanj '09 u 15:13 2009-06-04 15:13

Ako netko traži nešto naprednije, pokušajte s RequireJS . Dobit ćete dodatne pogodnosti kao što su upravljanje ovisnošću, poboljšana konkurentnost i izbjegavanje dupliciranja (tj. Dobivanje skripte više puta).

Možete napisati JavaScript datoteke u "module", a zatim ih nazvati ovisnostima u drugim skriptama. Ili možete koristiti RequireJS kao jednostavno rješenje "ići i dobiti ovu skriptu".

primjer:

Određivanje zavisnosti kao modula:

nešto dependency.js

border=0
 define(['lib/dependency1', 'lib/dependency2'], function (d1, d2) { //Your actual script goes here. //The dependent scripts will be fetched if necessary. return libraryObject; //For example, jQuery object }); 

creation.js je vaša "glavna" javascript datoteka, koja ovisi o nekim-dependency.js

 require(['some-dependency'], function(dependency) { //Your script goes here //some-dependency.js is fetched. //Then your script is executed }); 

Izvadak iz GitHub README:

RequireJS učitava jednostavne JavaScript datoteke, kao i više specifičnih modula. Optimiziran je za upotrebu u pregledniku, uključujući Web Worker, ali se može koristiti u drugim JavaScript okruženjima kao što su Rhino i Node. Ona implementira API asinkronog modula.

RequireJS koristi jednostavne skriptne oznake za učitavanje modula / datoteka, tako da bi trebao osigurati jednostavno otklanjanje pogrešaka. Može se koristiti samo za učitavanje postojećih JavaScript datoteka, tako da ga možete dodati u postojeći projekt bez potrebe za ponovnim pisanjem JavaScript datoteka.

...

532
07 июня '12 в 23:55 2012-06-07 23:55 Odgovor je dao John Strickler na Lipanj 07 '12 u 23:55 2012-06-07 23:55

Zapravo, postoji način za preuzimanje javascript datoteke ne asinkrono, tako da odmah nakon preuzimanja možete koristiti funkcije uključene u vašu nedavno prenesenu datoteku i mislim da radi u svim preglednicima.

Morate koristiti jQuery.append() u <head> elementu vaše stranice, to jest:

 $("head").append('<script type="text/javascript" src="' + script + '"></script>'); 

Međutim, ova metoda također ima problem: ako se pogreška pojavljuje u uvezenoj JavaScript datoteci, Firebug (kao i Firefox Console i Chrome Developer Tools također će pogrešno prijaviti svoju lokaciju, što je veliki problem ako koristite Firebug za puno praćenje pogrešaka JavaScripta ( Iz nekog razloga, Firebug jednostavno ne zna za nedavno prenesenu datoteku, pa ako se pojavi pogreška u toj datoteci, javlja se da se dogodila u glavnoj HTML datoteci i da ćete imati problema s pronalaženjem pravog uzroka pogreške.

Ali ako to nije problem za vas, onda bi ova metoda trebala funkcionirati.

Zapravo, napisao sam jQuery plugin pod nazivom $ .import_js () koji koristi ovu metodu:

 (function($) {  var import_js_imported = []; $.extend(true, { import_js : function(script) { var found = false; for (var i = 0; i < import_js_imported.length; i++) if (import_js_imported[i] == script) { found = true; break; } if (found == false) { $("head").append('<script type="text/javascript" src="' + script + '"></script>'); import_js_imported.push(script); } } }); })(jQuery); 

Stoga je sve što trebate uvesti JavaScript je:

 $.import_js('/path_to_project/scripts/somefunctions.js'); 

Također sam napravio jednostavan test za to u Primjeru .

Uključuje datoteku main.js u glavnom HTML-u, a zatim skripta u main.js koristi $.import_js() da uvozi dodatnu datoteku pod nazivom included.js , koja definira ovu funkciju:

 function hello() { alert("Hello world!"); } 

I odmah nakon uključivanja included.js , poziva se funkcija hello() i primit ćete obavijest.

(Ovaj odgovor je odgovor na e-sat komentar).

173
28 апр. Odgovori Kipras 28 tra. 2011-04-28 18:25 '11 u 18:25 2011-04-28 18:25

Drugi način koji je, po mom mišljenju, mnogo čišći, je napraviti sinkroni Ajax zahtjev umjesto korištenja <script> . Osim toga, obrađuje Node.js.

Evo primjera korištenja jQuery:

 function require(script) { $.ajax({ url: script, dataType: "script", async: false, // <-- This is the key success: function () { // all good... }, error: function () { throw new Error("Could not load script " + script); } }); } 

Tada ga možete koristiti u svom kodu, kao da se obično koristi uključuje:

 require("/scripts/subscript.js"); 

Funkciju možete pozvati iz potrebne skripte u sljedećem retku:

 subscript.doSomethingCool(); 
138
08 сент. Odgovor je dao Ariel rujan 08 2011-09-08 21:22 '11 u 21:22 2011-09-08 21:22

Dobre vijesti za vas. Vrlo brzo ćete moći lako učitati JavaScript kod. To će postati standardni način za uvoz modula JavaScript koda i postati dio same jezgre JavaScripta.

Vi samo trebate napisati import cond from 'cond.js'; učitajte makronaredbu pod nazivom cond iz datoteke cond.js

Dakle, ne morate se oslanjati na bilo koju JavaScript infrastrukturu i ne izričito upućujete Ajaxove pozive.

Pogledajte na:

90
03 июля '12 в 16:32 2012-07-03 16:32 odgovor je dan Imdad 03. srpnja '12 u 4:32 2012-07-03 16:32

Možete dinamički generirati JavaScript oznaku i dodati je u HTML dokument iz drugog JavaScript koda. To će učitati datoteku ciljnog JavaScripta.

 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"); 
78
04 июня '09 в 15:02 2009-06-04 15:02 je odgovorio Svitlanoj Maksymchuk dana 4. lipnja u 15:02 2009-06-04 15:02

operater import u ECMAScript 6.

sintaksa

 import name from "module-name"; import { member } from "module-name"; import { member as alias } from "module-name"; import { member1 , member2 } from "module-name"; import { member1 , member2 as alias2 , [...] } from "module-name"; import name , { member [ , [...] ] } from "module-name"; import "module-name" as name; 
61
17 апр. Odgovor dao draupnie 17. travnja 2015-04-17 04:56 '15 u 4:56 2015-04-17 04:56

Možda možete koristiti ovu funkciju koju sam pronašao na ovoj stranici.Kako mogu uključiti javascript datoteku u javascript datoteku? :

 function include(filename) { var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.src = filename; script.type = 'text/javascript'; head.appendChild(script) } 
51
04 июня '09 в 15:04 2009-06-04 15:04 Odgovor daje Arnaud Gouder de Beauregard Lipanj 04 '09 u 15:04 2009-06-04 15:04

Ovdje je sinkronizirana verzija bez jQuery :

 function myRequire( url ) { var ajax = new XMLHttpRequest(); ajax.open( 'GET', url, false ); // <-- the 'false' makes it synchronous ajax.onreadystatechange = function () { var script = ajax.response || ajax.responseText; if (ajax.readyState === 4) { switch( ajax.status) { case 200: eval.apply( window, [script] ); console.log("script loaded: ", url); break; default: console.log("ERROR: script not loaded: ", url); } } }; ajax.send(null); } 

Imajte na umu da će poslužitelj za dobivanje ove radne domene u odgovoru morati postaviti zaglavlje allow-origin .

47
11 дек. Odgovor daje heinob 11. prosinca. 2013-12-11 14:54 '13 u 14:54 2013-12-11 14:54

Upravo sam napisao ovaj javascript kôd (koristeći prototip za upravljanje DOM-om ):

 var require = (function() { var _required = {}; return (function(url, callback) { if (typeof url == 'object') { // We've (hopefully) got an array: time to chain! if (url.length > 1) { // Load the nth file as soon as everything up to the // n-1th one is done. require(url.slice(0, url.length - 1), function() { require(url[url.length - 1], callback); }); } else if (url.length == 1) { require(url[0], callback); } return; } if (typeof _required[url] == 'undefined') { // Haven't loaded this URL yet; gogogo! _required[url] = []; var script = new Element('script', { src: url, type: 'text/javascript' }); script.observe('load', function() { console.log("script " + url + " loaded."); _required[url].each(function(cb) { cb.call(); // TODO: does this execute in the right context? }); _required[url] = true; }); $$('head')[0].insert(script); } else if (typeof _required[url] == 'boolean') { // We already loaded the thing, so go ahead. if (callback) { callback.call(); } return; } if (callback) { _required[url].push(callback); } }); })(); 

Upotreba:

 <script src="prototype.js"></script> <script src="require.js"></script> <script> require(['foo.js','bar.js'], function () {  }); </script> 

Dno crta: http://gist.github.com/284442 .

43
23 янв. odgovor dano nornagon 23. siječnja 2010-01-23 08:20 '10 u 8:20 2010-01-23 08:20

Evo generalizirane verzije načina na koji to radi Facebook za svoju sveprisutnu tipku Like:

http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ . 

36
08 июля '15 в 5:41 2015-07-08 05:41 odgovor je dan Dan Dascalescu 08. '15. u 5:41 2015-07-08 05:41

Ako želite čisto javascript, možete koristiti document.write .

 document.write('<script src="myscript.js" type="text/javascript"></script>'); 

Ako koristite knjižnicu jQuery, možete koristiti metodu $.getScript .

 $.getScript("another_script.js"); 
30
13 нояб. Odgovor daje Venu immadi 13. studenog 2013-11-13 12:18 '13 u 12:18 2013-11-13 12:18

To je vjerojatno najveća slabost JavaScripta po mom mišljenju. Tijekom godina nisam imao problema s praćenjem ovisnosti. U svakom slučaju, čini se da je jedino praktično rješenje korištenje skripte uključene u HTML datoteku, te je stoga strašno učiniti vaš JavaScript kôd ovisnim o korisniku, uključujući i izvor koji vam je potreban, te učiniti njegovu ponovnu upotrebu neprijateljskom.

Oprostite ako ovo zvuči kao predavanje;) To je moja (loša) navika, ali želim to naglasiti.

Problem se vraća na sve ostalo na webu, u povijest javascripta. To doista nije bilo osmišljeno kako bi se koristilo u današnjem širokom rasprostranjenju. Netscape je stvorio jezik koji će vam omogućiti da upravljate s nekoliko stvari, ali oni nisu pretpostavili njegovu široku uporabu za mnoge stvari, kao što je to sada uobičajeno, i iz nekog razloga se proširilo od tamo, bez utjecaja na neke od temeljnih slabosti izvorne strategije.

Naravno, ovo nije jedan. HTML nije dizajniran za modernu web-stranicu; osmišljen je da izrazi logiku dokumenta, tako da ga čitatelji (preglednici u suvremenom svijetu) mogu prikazati u prikladnom obliku koji je bio unutar mogućnosti sustava, i trebalo je godinama da se riješi (osim hakiranja MS-a i Netscape-a). CSS rješava ovaj problem, ali već je dugo vremena, pa i dulje, ljude natjerao da ga koriste, a ne uspostavljene BAD metode. Dogodilo se, pohvala.

Nadamo se da će JavaScript (posebno sada kada je dio standarda) biti razvijen kako bi prihvatio koncept ispravne modularnosti (kao i neke druge stvari), kao i bilo koji drugi (postojeći) programski jezik na svijetu, i ta će glupost nestati. Sve dok vam se ne sviđa i ne prihvatam to, bojim se.

30
24 мая '12 в 12:51 2012-05-24 12:51 Odgovor daje Stephen Whipp on May 24 '12 at 12:51 2012-05-24 12:51

Većina ovdje prikazanih rješenja pretpostavlja dinamičko opterećenje. Umjesto toga, tražio sam prevodilac koji prikuplja sve ovisne datoteke u jednu izlaznu datoteku. Baš kao i Pre- @import Less / Sass @import s pravilom CSS @import . Budući da nisam pronašao ništa slično, napisao sam jednostavan alat za rješavanje problema.

Dakle, ovdje je kompajler https://github.com/dsheiko/jsic , koji pouzdano zamjenjuje $import("file-path") traženim sadržajem datoteke. Ovdje je odgovarajući Grunt dodatak: https://github.com/dsheiko/grunt-jsic .

U glavnom jQuery threadu, oni jednostavno spajaju atomske izvorne datoteke u jednu, počevši s intro.js i završavajući s outtro.js . To mi ne odgovara, jer ne pruža fleksibilnost u razvoju izvornog koda. Provjerite kako funkcionira s JSIC:

Src / main.js

 var foo = $import("./Form/Input/Tel"); 

SRC / Form / login /Tel.js

 function() { return { prop: "", method: function(){} } } 

Sada možemo pokrenuti kompajler:

 node jsic.js src/main.js build/mail.js 

I nabavite spojenu datoteku

build /main.js

 var foo = function() { return { prop: "", method: function(){} } }; 
24
14 июля '13 в 0:44 2013-07-14 00:44 odgovor je dao Dmitry Sheiko 14. srpnja '13. u 0:44 2013-07-14 00:44

Skripte možete izraditi i pomoću PHP-a :

Datoteka main.js.php :

 <?php header('Content-type:text/javascript; charset=utf-8'); include_once("foo.js.php"); include_once("bar.js.php"); ?> // Main JavaScript code goes here 
24
28 дек. Odgovor je dao Calmarius 28. prosinca. 2010-12-28 00:03 '11 u 0:03 2010-12-28 00:03

Ako vaša namjera za učitavanje JavaScript datoteke koristi funkcije iz uvezene / uključene datoteke , također možete definirati globalni objekt i postaviti funkcije kao elemente objekta. Na primjer:

global.js

 A = {}; 

file1.js

 A.func1 = function() { console.log("func1"); } 

file2.js

 A.func2 = function() { console.log("func2"); } 

main.js

 A.func1(); A.func2(); 

Vi samo trebate biti oprezni kada uključite skripte u HTML datoteku. Narudžba bi trebala biti kao što je prikazano u nastavku:

 <head> <script type="text/javascript" src="global.js"></script> <script type="text/javascript" src="file1.js"></script> <script type="text/javascript" src="file2.js"></script> <script type="text/javascript" src="main.js"></script> </head> 
20
24 июля '15 в 9:53 2015-07-24 09:53 odgovor je dao Adem İlhan 24. srpnja '15 u 9:53 2015-07-24 09:53

To bi trebalo učiniti:

 xhr = new XMLHttpRequest(); xhr.open("GET", "/soap/ajax/11.0/connection.js", false); xhr.send(); eval(xhr.responseText); 
18
24 марта '13 в 22:32 2013-03-24 22:32 odgovor je dan tggagne 24. ožujka '13 u 10:32 2013-03-24 22:32

Ili umjesto da ga uključite tijekom izvođenja, upotrijebite skriptu za spajanje prije učitavanja.

Koristim Zvjezdice (ne znam ima li drugih). Vi gradite svoj JavaScript kod u odvojenim datotekama i uključite komentare koji su obrađeni mehanizmom Sprockets, baš kao i oni uključeni. Za razvoj možete sekvencijalno uključiti datoteke, a zatim za proizvodnju, kombinirati ih ...

Pogledajte i:

17
07 июня '12 в 23:48 2012-06-07 23:48 odgovor je dao JMawer na Lipanj 07 '12 u 23:48 2012-06-07 23:48

Ako koristite Web Workers i želite uključiti dodatne skripte u područje zaposlenika, ostale odgovore o dodavanju skripti u oznaku head itd. Neće raditi za vas.

Srećom, Web Workers ima vlastitu funkciju importScripts koja je globalna funkcija u području Web Worker, ugrađena u sam preglednik, budući da je dio specifikacije .

Osim toga, kao drugi najučestaliji odgovor na vaše pitanje , RequireJS također može obraditi uključivanje skripti unutar Web Workera (vjerojatno samih importScripts , ali s nekoliko drugih korisnih značajki).

14
01 янв. Odgovor je dao Turnerj 01. siječnja 2015-01-01 11:58 '15 u 11:58 2015-01-01 11:58