Kaip įtraukti „JavaScript“ failą į kitą „JavaScript“ failą?

Ar „JavaScript“ turi kažką panašaus į „CSS @import kuri leidžia įtraukti „JavaScript“ failą į kitą „JavaScript“ failą?

4465
04 июня '09 в 14:59 2009-06-04 14:59 „Alec Smart “ nustatytas birželio 4 d., 09:59, 2009-06-04 14:59
@ 56 atsakymai
  • 1
  • 2

Senesnėse „JavaScript“ versijose nebuvo importo, įtraukimo ar reikalavimo, todėl buvo sukurta daug skirtingų požiūrių į šią problemą.

Tačiau nuo 2015 m. (ES6) „JavaScript“ sistemoje pasirodė ES6 modulių, skirtų modulių importavimui į „Node.js“, standartas .

Jei norite suderinti su senesnėmis naršyklėmis, galite naudoti kūrimo ir (arba) perdavimo įrankius.

ES6 moduliai

„ECMAScript“ (ES6) moduliai yra palaikomi „Node.js“, nes versija - --experimental-modules vėliavos --experimental-modules . Visi .mjs failai turi turėti .mjs plėtinį.

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

ECMAScript moduliai naršyklėse

Naršyklės palaiko įkrovos ECMAScript modulius tiesiogiai (nereikia jokių įrankių, pvz., „Webpack“), pradedant „ Safari 10.1“, „Chrome“ 61, „Firefox 60“ ir „Edge 16“.

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

Sužinokite daugiau šiuo adresu: https://jakearchibald.com/2017/es-modules-in-browsers/

Dinaminis importavimas naršyklėse

Dinaminis importavimas leidžia scenarijai įkelti kitus scenarijus, kai reikia:

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

Node.js reikalauja

Senas modulio importo stilius, vis dar plačiai naudojamas „Node.js“, yra modulio.exportas / reikalinga sistema .

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

Yra ir kitų būdų įgalinti „JavaScript“ išorinį turinį naršyklėse, kurioms nereikia išankstinio apdorojimo.

AJAX atsisiuntimas

Galite įkelti papildomą scenarijų naudodami AJAX skambutį, tada naudokite eval kad jį paleistumėte. Tai paprasčiausias būdas, tačiau jis taikomas tik jūsų domenui dėl „JavaScript“ sandbox saugumo modelio. eval taip pat atveria kelią klaidoms, įsilaužimams ir saugumo problemoms.

Atsisiųsti atsisiuntimą

Kaip ir dinamiškam importui, galite įkelti vieną ar daugiau scenarijų skambinant fetch pažadais valdyti tvarką, pagal kurią scenarijų priklausomybės vykdomos naudojant „ Fetch Inject“ biblioteką:

 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 pakrovimas

JQuery“ biblioteka pateikia vieno eilutės pakrovimą:

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

Ši funkcija prideda naują <script> puslapio galo dalies pabaigą, kur src atributas nustatomas į URL, kuris perduodamas funkcijai kaip pirmasis parametras.

Abu šie sprendimai aptariami ir iliustruojami „ JavaScript“ beprotybėje: dinaminis scenarijų įkėlimas .

Aptikimas, kai scenarijus buvo įvykdytas

Dabar yra didelė problema, kurią turėtumėte žinoti. Tai reiškia, kad atsisiųsite kodą nuotoliniu būdu. Šiuolaikinės žiniatinklio naršyklės įkelia failą ir toliau atlieka jūsų dabartinį scenarijų, nes jie viską įkelia asinchroniškai, kad pagerintų našumą. (Tai taikoma ir jQuery metodui, ir rankinio dinaminio scenarijaus įkėlimo metodui.)

Tai reiškia, kad jei naudosite šiuos gudrybės tiesiogiai, negalėsite naudoti naujai atsisiųsti kodo kitoje eilutėje po to, kai paprašėte jį atsisiųsti, nes jis vis tiek bus įkeltas.

Pavyzdžiui: my_lovely_script.js yra „ 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); } 

Tada rašysite kodą, kurį norite naudoti po to, kai scenarijus įkeliamas į lambda funkciją :

 loadScript("my_lovely_script.js", myPrettyCode); 

Atkreipkite dėmesį, kad scenarijus gali būti vykdomas įkėlus DOM arba anksčiau, priklausomai nuo naršyklės ir nuo to, ar script.async = false; eilutė script.async = false; Yra puikus straipsnis apie „Javascript“ atsisiuntimą apskritai .

Pradinio kodo sujungimas / išankstinis apdorojimas

Kaip minėta šio atsakymo viršuje, daugelis kūrėjų savo projektuose naudoja statybinius / perkėlimo įrankius, pvz., „Parcel“, „Webpack“ arba „Babel“, kurie leidžia jiems naudoti būsimą „JavaScript“ sintaksę, suteikti atgalinį suderinamumą su senesnėmis naršyklėmis, sujungti failus, sumažinti suskaidymo kodą ir pan

3838
04 июня '09 в 15:13 2009-06-04 15:13 atsakymas pateikiamas e-satis 04 birželio 09 d. 15:13 2009-06-04 15:13

Jei kas nors ieško kažko labiau pažengusio, pabandykite „ RequireJS“ . Jūs gausite papildomų privalumų, tokių kaip priklausomybės valdymas, pagerėjęs sutapimas ir dubliavimo išvengimas (ty scenarijaus gavimas daugiau nei vieną kartą).

Savo „JavaScript“ failus galite įrašyti į „modulius“ ir tada juos nurodyti kaip priklausomybę kitose scenarijose. Arba galite naudoti „RequireJS“ kaip paprastą „eiti ir gauti šį scenarijų“ sprendimą.

Pavyzdys:

Nustatykite priklausomybes kaip modulius:

some-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 yra „pagrindinis“ „JavaScript“ failas, kuris priklauso nuo kai kurių priklausomybės.js

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

Ištrauka iš „ GitHub README“:

„RequireJS“ įkelia paprastus „JavaScript“ failus ir konkrečius modulius. Jis yra optimizuotas naudoti naršyklėje, įskaitant žiniatinklio darbuotoją, tačiau gali būti naudojamas kitose „JavaScript“ aplinkose, pvz., „Rhino“ ir „Node“. Jis įgyvendina asinchroninį modulio API.

„RequireJS“ naudoja paprastus scenarijų žymenis modulių / failų įkėlimui, todėl ji turėtų užtikrinti paprastą derinimą. Jis gali būti naudojamas tiesiog įkelti esamus „JavaScript“ failus, kad galėtumėte jį pridėti prie esamo projekto, nereikia perrašyti „JavaScript“ failų.

...

532
07 июня '12 в 23:55 2012-06-07 23:55 Atsakymą pateikė John Strickler birželio 12 d. 12 val. 23:55 2012-06-07 23:55

Tiesą sakant, yra būdas atsisiųsti „JavaScript“ failą ne asinchroniškai, todėl jūs galite naudoti naujai įkelto failo funkcijas iškart po atsisiuntimo ir manau, kad jis veikia visose naršyklėse.

Jūsų puslapio <head> elemente turite naudoti jQuery.append() :

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

Tačiau šis metodas taip pat turi problemų: jei importuojamame „JavaScript“ faile įvyksta klaida, „ Firebug“ (taip pat „Firefox“ klaidų konsolė ir „ Chrome“ kūrėjų įrankiai taip pat neteisingai praneša apie savo vietą, o tai yra didelė problema, jei naudojate „Firebug“, kad galėtumėte daug stebėti „JavaScript“ klaidas Dėl kažkokių priežasčių „Firebug“ tiesiog nežino apie neseniai įkeltą failą, todėl, jei šiame faile įvyksta klaida, ji praneša, kad ji įvyko pagrindiniame HTML faile, ir jums bus sunku rasti tikrąją klaidos priežastį.

Bet jei tai nėra problema jums, tada šis metodas turėtų veikti.

Tiesą sakant, parašiau „jQuery“ papildinį, vadinamą $ .import_js (), kuris naudoja šį metodą:

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

Todėl viskas, ką jums reikia padaryti, kad importuotumėte „JavaScript“:

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

Aš taip pat atlikau paprastą šio pavyzdžio bandymą.

Į pagrindinį HTML failą įtrauktas pagrindinis.js failas, o pagrindiniame faile „script“ pagrindiniame main.js $.import_js() importuojamas papildomas failas, pavadintas $.import_js() , kuris apibrėžia šią funkciją:

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

Ir iš karto po to, kai included.js hello() vadinama „ hello() funkcija ir gausite pranešimą.

(Šis atsakymas yra atsakymas į e-sat komentarą).

173
28 апр. Atsakyti Kipras 28 bal. 2011-04-28 18:25 '11, 18:25, 2011-04-28 18:25

Kitas būdas, kuris, mano nuomone, yra daug švaresnis, yra sinchroninio „Ajax“ užklausos vietoj to, kad būtų naudojamas <script> . Be to, ji apdoroja „ Node.js.“

Čia pateikiamas jQuery naudojimo pavyzdys:

 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 galite jį naudoti savo kode, kaip paprastai, įskaitant:

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

Taip pat galite skambinti funkcijai iš reikiamo scenarijaus šioje eilutėje:

 subscript.doSomethingCool(); 
138
08 сент. Atsakymą pateikė Ariel Sep 08 2011-09-08 21:22 '11, 21:22, 2011-09-08 21:22

Geros žinios jums. Labai greitai galėsite lengvai įkelti „JavaScript“ kodą. Tai taps standartiniu būdu importuoti „JavaScript“ kodo modulius ir tapti paties „JavaScript“ branduolio dalimi.

Jūs tiesiog turite rašyti import cond from 'cond.js'; įkelkite makrokomandą, pavadintą condcond.js failo

Taigi nereikia pasikliauti jokia „JavaScript“ infrastruktūra ir aiškiai nenurodykite „ Ajax“ skambučių.

Žr.

90
03 июля '12 в 16:32 2012-07-03 16:32 atsakymas pateikiamas Imdad liepos 03 d. 12 val. 4:32 2012-07-03 16:32

Galite dinamiškai generuoti „JavaScript“ žymą ir pridėti jį prie kito „JavaScript“ kodo HTML dokumento. Tai įkels tikslinį „JavaScript“ failą.

 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 atsakė Svitlana Maksymchuk'ui birželio 04 d., 09:15, 2009-06-04 15:02

import operatorius ECMAScript 6.

Sintaksė

 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 апр. Atsakymas, kurį pateikė 17 d 2015-04-17 04:56 '15 at 4:56 2015-04-17 04:56

Galbūt jūs galite naudoti šią funkciją, kurią suradau šiame puslapyje. Kaip įtraukti javascript failą į javascript failą? :

 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 Atsakymą pateikė „ Arnaud Gouder de Beauregard“ birželio 4 d.

Čia yra sinchroninė versija be „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); } 

Atkreipkite dėmesį, kad norint gauti šį darbo domeną, serveryje savo atsakyme turės nustatyti allow-origin .

47
11 дек. atsakymas duotas heinob 11 Dec 2013-12-11 14:54 '13, 14:54, 2013-12-11 14:54

Aš tiesiog parašiau šį „JavaScript“ kodą (naudojant prototipą manipuliuoti DOM ):

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

Naudoti:

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

Apatinė eilutė: http://gist.github.com/284442 .

43
23 янв. atsakymas duotas nornagon sausio 23 d 2010-01-23 08:20 '10, 8:20, 2010-01-23 08:20

Čia yra apibendrinta versija, kaip „Facebook“ tai daro dėl visur esančių panašių mygtukų:

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

36
08 июля '15 в 5:41 2015-07-08 05:41 atsakymas duotas Dan Dascalescu liepos 08-15 dienomis 5:41 2015-07-08 05:41

Jei norite gryno javascript, galite naudoti document.write .

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

Jei naudojate jQuery biblioteką, galite naudoti $.getScript metodą.

 $.getScript("another_script.js"); 
30
13 нояб. Atsakymą pateikė Venu immadi 13 lapkritis. 2013-11-13 12:18 '13, 12:18, 2013-11-13 12:18

Tai, mano nuomone, yra didžiausias „JavaScript“ trūkumas. Per daugelį metų neturėjau problemų, susijusių su priklausomybių sekimu. Bet kuriuo atveju, atrodo, kad vienintelis praktinis sprendimas yra naudoti HTML faile esantį scenarijų, todėl baisu padaryti jūsų „JavaScript“ kodą priklausomą nuo vartotojo, įskaitant reikalingą šaltinį, ir padaryti jį pakartotinai naudingą.

Atsiprašau, jei tai skamba kaip paskaita;) Tai mano (blogas) įprotis, bet noriu tai pabrėžti.

Problema grįžta į viską, kas yra žiniatinklyje, į javascript istoriją. Jis tikrai nebuvo skirtas naudoti plačiai paplitusioje šiandien. „Netscape“ sukūrė kalbą, kuri leistų jums valdyti kelis dalykus, tačiau jie neprisiėmė savo plačiai paplitusio naudojimo daugeliui dalykų, kaip dabar yra įprasta, ir dėl vienos ar kitos priežasties ji išaugo, nepaveikdama kai kurių esminių pradinės strategijos trūkumų.

Tai nėra žinoma. HTML nebuvo sukurtas šiuolaikiniam tinklalapiui; ji buvo sukurta taip, kad išreikštų dokumento logiką, kad skaitytojai (šiuolaikinio pasaulio naršyklės) galėtų ją parodyti tinkama forma, kuri atitiktų sistemos galimybes, ir išspręsti reikėjo metų (išskyrus įsilaužimą į MS ir Netscape). CSS išsprendžia šią problemą, bet ilgai ir net ilgiau, kad žmonės jį naudotųsi, o ne nustatytus BAD metodus. Tai atsitiko, girti.

Tikimės, kad „JavaScript“ (ypač dabar ji yra standarto dalis) bus sukurta siekiant priimti teisingo moduliškumo (taip pat ir kitų dalykų), kaip ir bet kurios kitos (esamos) programavimo kalbos pasaulyje koncepciją, ir ši nesąmonė išnyks. Kol tik patiksite ir aš to nepritariu, aš bijo.

30
24 мая '12 в 12:51 2012-05-24 12:51 Atsakymą pateikė Stephen Whipp gegužės 12 d. 12:51 2012-05-24 12:51

Dauguma čia pateiktų sprendimų pritaiko dinaminį pakrovimą. Vietoj to, aš ieškojau kompiliatoriaus, kuris renka visus priklausomus failus į vieną išvesties failą. Panašiai kaip ir mažiau / sass @import turintys CSS @import taisyklę. Kadangi neradau nieko panašaus, parašiau paprastą problemos sprendimo priemonę.

Taigi, čia yra https://github.com/dsheiko/jsic kompiliatorius, kuris patikimai pakeičia $import("file-path") prašomu failo turiniu. Čia yra tinkamas „ Grunt“ papildinys: https://github.com/dsheiko/grunt-jsic .

Pagrindiniame jQuery gijoje jie tiesiog sujungia atomo šaltinio failus į vieną, pradedant intro.js ir baigdami outtro.js . Tai netinka man, nes nesuteikia lankstumo kuriant šaltinį. Sužinokite, kaip jis veikia su JPI:

Src / main.js

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

SRC / Forma / prisijungimas /Tel.js

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

Dabar mes galime paleisti kompiliatorių:

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

Ir gaukite sujungtą failą

build /main.js

 var foo = function() { return { prop: "", method: function(){} } }; 
24
14 июля '13 в 0:44 2013-07-14 00:44 atsakymą pateikė Dmitrijus Šeikas liepos 14 d., 13 val. 0:44 2013-07-14 00:44

Taip pat galite kurti savo scenarijus naudodami PHP :

Failas 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 дек. Atsakymą pateikė Calmarius, gruodžio 28 d. 2010-12-28 00:03 '11 - 0:03 2010-12-28 00:03

Jei ketinate įkelti „JavaScript“ failą, naudokite importuotos / įtrauktos rinkmenos funkcijas , taip pat galite apibrėžti pasaulinį objektą ir nustatyti funkcijas kaip objektų elementus. Pavyzdžiui:

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

Jums tereikia būti atsargiems, kai į HTML failą įtraukiate scenarijus. Užsakymas turėtų būti toks, kaip nurodyta toliau:

 <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 atsakymą pateikė Adem İlhan liepos 24 d., 15 val. 9:53 2015-07-24 09:53

Tai turėtų daryti:

 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 atsakymas duotas kovo 13 d., 13 d., 10:32, 2013-03-24 22:32

Arba vietoj to, kad jį įjungtumėte vykdydami, naudokite scenarijų, kad galėtumėte sujungti.

Aš naudoju žvaigždutes (nežinau, ar yra kitų). Jūs sukuriate savo „JavaScript“ kodą atskiruose failuose ir įtraukiate komentarus, kuriuos apdoroja „Sprockets“ mechanizmas, kaip ir įtraukti. Jei norite plėtoti, galite įtraukti failus iš eilės, o tada - gamybai, kad juos sujungtumėte ...

Taip pat žiūrėkite:

17
07 июня '12 в 23:48 2012-06-07 23:48 atsakymą pateikė JMawer birželio 12 d. 12 val. 23:48 2012-06-07 23:48

Jei naudojatės žiniatinklio darbuotojais ir norite įtraukti papildomus scenarijus į darbuotojo sritį, kitus atsakymus apie scenarijų įtraukimą į head žymę ir tt Nieko neveiks.

Laimei, „ Web Workers“ turi savo funkciją „ importScripts kuri yra pasaulinė funkcija „Web Worker“ srityje, įtraukta į pačią naršyklę, nes ji yra specifikacijos dalis .

Be to, kaip antras labiausiai įvertintas atsakymas į jūsų klausimą , „ RequireJS“ taip pat gali tvarkyti scenarijų įtraukimą į „Web Worker“ (tikriausiai pats skambinantis importScripts , bet su keliomis kitomis naudingomis funkcijomis).

14
01 янв. Atsakymą pateikė Turnerj Jan 01 2015-01-01 11:58 '15 at 11:58 2015-01-01 11:58

Aš turėjau paprastą problemą, bet man nepatiko atsakymai į šį klausimą.