Как да включим javascript файла в друг javascript файл?

Има ли JavaScript нещо подобно на @import в CSS, което ви позволява да включите javascript файл в друг javascript файл?

4465
04 июня '09 в 14:59 2009-06-04 14:59 Алек Смарт е настроен за 04 Юни в 14:59 2009-06-04 14:59
@ 56 отговора
  • 1
  • 2

В по-старите версии на JavaScript нямаше никакъв внос, включване или изискване, поради което бяха разработени много различни подходи към този проблем.

Но от 2015 г. (ES6) стандартът на ES6 модулите за импортиране на модули в Node.js се появи в JavaScript, който също се поддържа от повечето съвременни браузъри .

За съвместимост с по-старите браузъри можете да използвате инструментите за изграждане и / или трансфер .

Модули ES6

Модулите ECMAScript (ES6) се поддържат от Node.js, тъй като версия - --experimental-modules флаг - --experimental-modules . Всички .mjs файлове трябва да имат разширение .mjs .

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

ECMAScript модули в браузъри

Браузърите поддържат директно зареждане на модули ECMAScript (не се изискват инструменти като Webpack), започвайки с Safari 10.1, Chrome 61, Firefox 60 и Edge 16. Проверете текущата поддръжка в caniuse .

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

Научете повече на адрес https://jakearchibald.com/2017/es-modules-in-browsers/

Динамичен импорт в браузърите

Динамичният импорт позволява на скрипта да зарежда други скриптове, ако е необходимо:

адрес https://developers.google.com/web/updates/2017/11/dynamic-import. 

Node.js изисква

Старият модул за импортиране на модул, все още широко използван в Node.js, е модулът.exports / require .

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

Има и други начини за активиране на външно съдържание на JavaScript в браузъри, които не изискват предварителна обработка.

AJAX Изтегли

Можете да заредите допълнителен скрипт с AJAX повикване и след това да използвате eval за да го eval . Това е най-лесният начин, но той е ограничен до домейна ви поради модела за защита на пясъчника на JavaScript. Използването на eval също отваря пътя към бъгове, хакерство и проблеми със сигурността.

Изтегляне Изтегляне

Както при динамичния внос, можете да заредите един или повече скриптове, като извикате fetch с помощта на обещания, за да контролирате реда, в който скриптовите зависимости се изпълняват чрез библиотеката 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 зареждане

Библиотеката jQuery осигурява единично зареждане:

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

Тази функция ще добави нов <script> в края на раздела за глава на страницата, където атрибутът src е настроен на URL, който се предава на функцията като първи параметър.

И двете решения се обсъждат и илюстрират в JavaScript Madness: динамично зареждане на скриптове .

Откриване при изпълнение на скрипта

Сега има голям проблем, за който трябва да сте наясно. Това означава, че изтегляте кода дистанционно. Съвременните уеб браузъри зареждат файла и продължават да изпълняват текущия ви скрипт, защото зареждат всичко асинхронно, за да подобрят производителността. (Това се отнася както за метода jQuery, така и за метода за ръчно зареждане на динамичен скрипт.)

Това означава, че ако използвате тези трикове директно, няма да можете да използвате новия си изтеглен код на следващия ред, след като сте го помолили да го изтеглите, тъй като той все още ще се зарежда.

Например: my_lovely_script.js съдържа 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); } 

След това напишете кода, който искате да използвате след като скриптът е зареден в lambda функцията :

 loadScript("my_lovely_script.js", myPrettyCode); 

Обърнете внимание, че скриптът може да бъде изпълнен след зареждането на DOM или по-рано, в зависимост от браузъра и дали script.async = false; е активиран script.async = false; Има голяма статия за изтегляне на Javascript като цяло, която обсъжда това.

Сливане / предварителна обработка на изходния код

Както беше споменато в началото на този отговор, много разработчици използват инструменти за изграждане / прехвърляне в своите проекти, като Parcel, Webpack или Babel. и така нататък

3838
04 июня '09 в 15:13 2009-06-04 15:13 отговорът е даден e-satis 04 юни '09 в 15:13 2009-06-04 15:13

Ако някой търси нещо по-напреднало, опитайте RequireJS . Ще получите допълнителни предимства като управление на зависимостта, подобрена съвместимост и избягване на дублиране (т.е. получаване на скрипта повече от веднъж).

Можете да напишете вашите JavaScript файлове в "модули" и след това да ги наричате зависимости в други скриптове. Или можете да използвате RequireJS като просто решение "отидете и да получите този скрипт".

например:

Дефинирайте зависимости като модули:

някои-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 е вашият "главен" javascript файл, който зависи от някои-dependency.js

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

Извадка от GitHub README:

RequireJS зарежда прости JavaScript файлове, както и по-специфични модули. Той е оптимизиран за използване в браузъра, включително Web Worker, но може да се използва и в други JavaScript среди, като Rhino и Node. Той изпълнява асинхронния модул API.

RequireJS използва прости скриптови тагове за зареждане на модули / файлове, така че трябва да осигурява лесно отстраняване на грешки. Може да се използва само за зареждане на съществуващи JavaScript файлове, така че можете да го добавите към съществуващ проект, без да се налага да пренаписвате JavaScript файловете.

...

532
07 июня '12 в 23:55 2012-06-07 23:55 Отговорът е от John Strickler на 07.06.2012 г. в 23:55 ч. 2012-06-07 23:55

В действителност, има начин да изтеглите javascript файл не асинхронно, така че можете да използвате функциите, включени в новия ви файл веднага след изтеглянето, и мисля, че работи във всички браузъри.

Трябва да използвате jQuery.append() в <head> елемента на страницата си, т.е.

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

Въпреки това, този метод също има проблем: ако възникне грешка в импортирания JavaScript файл, Firebug (както и конзолата за грешки на Firefox и инструментите за разработчици на Chrome също ще докладват местоположението си неправилно, което е голям проблем, ако използвате Firebug за много проследяване на грешки в JavaScript ( По някаква причина, Firebug просто не знае за наскоро качения файл, така че ако възникне грешка в този файл, той съобщава, че е възникнал във вашия основен HTML файл и ще имате проблеми при намирането на истинската причина за грешката.

Но ако това не е проблем за вас, тогава този метод трябва да работи.

Всъщност написах плъгин jQuery, наречен $ .import_js (), който използва този метод:

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

Следователно, всичко, което трябва да направите, за да импортирате JavaScript е:

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

Също така направих прост тест за това в Пример .

Той включва main.js файла в основния HTML, а след това скриптът в main.js използва $.import_js() за импортиране на допълнителен файл, наречен included.js , който определя тази функция:

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

И веднага след включването на hello() се извиква функцията hello() и ще получите известие.

(Този отговор е отговор на коментара на e-sat).

173
28 апр. Отговор Kipras 28 апр. 2011-04-28 18:25 '11 в 18:25 2011-04-28 18:25

Друг начин, който според мен е много по-чист, е да се направи синхронна Ajax заявка вместо да се използва <script> . Освен това той обработва Node.js.

Ето пример за използване на 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); } }); } 

След това можете да го използвате в кода си, като че ли обикновено използвате: включват:

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

Можете да извикате функцията от необходимия скрипт в следния ред:

 subscript.doSomethingCool(); 
138
08 сент. Отговорът е даден от Ariel Sep 08 2011-09-08 21:22 '11 в 21:22 2011-09-08 21:22

Добри новини за вас. Много скоро ще можете лесно да зареждате JavaScript код. Това ще се превърне в стандартен начин за импортиране на JavaScript модули и ще стане част от самото ядро ​​на JavaScript.

Просто трябва да напишете import cond from 'cond.js'; cond.js макроса с име cond от файла cond.js

По този начин не е необходимо да разчитате на никаква JavaScript инфраструктура и не правите изрично Ajax повиквания.

Обърнете се към:

90
03 июля '12 в 16:32 2012-07-03 16:32 отговорът е даден Imdad 03 юли '12 в 4:32 2012-07-03 16:32

Можете динамично да генерирате маркер на JavaScript и да го добавите към HTML документ от друг JavaScript код. Това ще зареди целевия 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"); 
78
04 июня '09 в 15:02 2009-06-04 15:02 отговори на Свиталана Максимчук на 04.06.2009 в 15:02 2009-06-04 15:02

оператор на import в ECMAScript 6.

синтаксис

 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 апр. Отговор, даден от draupnie на 17 април 2015-04-17 04:56 '15 в 4:56 2015-04-17 04:56

Може би можете да използвате тази функция, която открих на тази страница.Как да включа файла на javascript в файла на 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) } 
51
04 июня '09 в 15:04 2009-06-04 15:04 Отговорът е даден от Арно Гудер де Борегард Юни 04 '09 в 15:04 2009-06-04 15:04

Ето и синхронната версия без 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); } 

Забележете, че за да получите този работещ домейн, сървърът ще трябва да зададе заглавна част на allow-origin в отговора си.

47
11 дек. Отговорът е даден от heinob 11 декември. 2013-12-11 14:54 '13 в 14:54 2013-12-11 14:54

Току-що написах този javascript код (използвайки прототип за манипулиране на 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); } }); })(); 

Употреба:

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

Долната линия: http://gist.github.com/284442 .

43
23 янв. отговор даден nornagon 23 януари 2010-01-23 08:20 '10 в 8:20 2010-01-23 08:20

Тук е обобщена версия на това как Facebook прави това за вездесъщия си бутон Харесване:

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

36
08 июля '15 в 5:41 2015-07-08 05:41 отговорът е даден Dan Dascalescu 08 юли '15 в 5:41 2015-07-08 05:41

Ако искате чист javascript, можете да използвате document.write .

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

Ако използвате библиотеката jQuery, можете да използвате метода $.getScript .

 $.getScript("another_script.js"); 
30
13 нояб. Отговорът е даден от Venu immadi 13 ноември. 2013-11-13 12:18 '13 в 12:18 2013-11-13 12:18

Това е може би най-голямата слабост на JavaScript по мое мнение. През годините нямах проблем да проследявам зависимости. Във всеки случай, изглежда, че единственото практично решение е да се използва скрипт, включен в HTML файла, и затова е ужасно да се направи JavaScript кода си зависим от потребителя, включително от източника, от който се нуждаете, и да направи повторното му използване недружелюбно.

Съжалявам, ако това звучи като лекция;) Това е моят (лош) навик, но искам да подчертая това.

Проблемът се връща към всичко останало в интернет, към историята на javascript. Това наистина не е било предназначено да се използва в широкото разпространение, което използва днес. Netscape създаде език, който ще ви позволи да управлявате няколко неща, но те не приемат широкото му използване за много неща, както е прието сега, и по една или друга причина се разширява от там, без да се засягат някои от основните слабости на първоначалната стратегия.

Това, разбира се, не е едно. HTML не е предназначен за модерна уеб страница; тя е предназначена да изразява логиката на документа, така че читателите (браузърите в съвременния свят) да могат да го покажат в подходяща форма, която е в рамките на възможностите на системата, и са необходими години за решаване (освен хакването на MS и Netscape). CSS решава този проблем, но отдавна и дори по-дълго, за да накара хората да го използват, а не установените BAD методи. Случи се, похвала.

Надяваме се, че JavaScript (особено сега, когато е част от стандарта) ще бъде разработен, за да приеме концепцията за правилната модулност (както и някои други неща), като всеки друг (съществуващ) език за програмиране в света, и тази глупост ще изчезне. Докато не го харесате и аз не го приемам, страхувам се.

30
24 мая '12 в 12:51 2012-05-24 12:51 Отговорът е даден от Stephen Whipp на 24 май'12 в 12:51 ч. 2012-05-24 12:51

Повечето от представените тук решения приемат динамично натоварване. Вместо това търсех компилатор, който събира всички зависими файлове в един изходен файл. Точно като @import Less / Sass @import с правилото CSS @import . Тъй като не намерих нещо такова, написах прост инструмент за решаване на проблем.

Така че, тук е компилатора https://github.com/dsheiko/jsic , който надеждно заменя $import("file-path") исканото съдържание на файла. Ето подходящия плъгин на Grunt : https://github.com/dsheiko/grunt-jsic .

В основната нишка на jQuery, те просто обединяват атомни източници в един, започвайки с intro.js и завършвайки с outtro.js . Това не ми подхожда, тъй като не осигурява гъвкавост при разработването на изходния код. Вижте как работи с JSIC:

Src / main.js

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

SRC / Form / login /Tel.js

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

Сега можем да стартираме компилатора:

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

И вземете обединения файл

build /main.js

 var foo = function() { return { prop: "", method: function(){} } }; 
24
14 июля '13 в 0:44 2013-07-14 00:44 отговорът е даден от Дмитрий Шейко 14 юли '13 в 0:44 2013-07-14 00:44

Можете също така да създавате скриптове с помощта на PHP :

Файл 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 дек. Отговорът е даден от Калмариус на 28 декември. 2010-12-28 00:03 '11 в 0:03 2010-12-28 00:03

Ако намерението ви да качите JavaScript файл използва функции от импортирания / включен файл , можете също да дефинирате глобален обект и да зададете функции като елементи на обекта. Например:

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

Трябва само да внимавате, когато включите скриптове в HTML файла. Поръчката трябва да бъде както е показано по-долу:

 <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 отговорът е даден от Adem İlhan 24 юли '15 в 9:53 2015-07-24 09:53

Това трябва да се направи:

 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 отговорът е даден tggagne 24 март '13 в 10:32 2013-03-24 22:32

Или вместо да го включите по време на изпълнение, използвайте скрипт за сливане преди зареждане.

Използвам звездички (не знам дали има други). Вие изграждате своя JavaScript код в отделни файлове и включвате коментари, които се обработват от механизма Sprockets, точно като включените. За разработване можете да включите файлове последователно, а след това и за производство, за да ги комбинирате ...

Вижте също:

17
07 июня '12 в 23:48 2012-06-07 23:48 Отговорът е даден от JMawer на 07 юни '12 в 23:48 ч. 2012-06-07 23:48

Ако използвате Web Workers и искате да включите допълнителни скриптове в областта на служителите, други отговори за добавяне на скриптове в тага за head и др. Няма да работи за вас.

За щастие, Web Workers има своя собствена функция importScripts която е глобална функция в областта на Web Worker, вградена в самия браузър, тъй като е част от спецификацията .

В допълнение, като вторият най-високо оценен отговор на вашия въпрос , RequireJS може да се справи и с включването на скриптове в Web Worker (вероятно самият importScripts , но с няколко други полезни функции).

14
01 янв. Отговорът е даден от Turnerj Jan 01 2015-01-01 11:58 '15 в 11:58 2015-01-01 11:58

Имах един прост проблем, но бях озадачен от отговорите на този въпрос.

Трябваше да използвам променлива (myVar1), дефинирана в един JavaScript файл (myvariables.js) в друг JavaScript файл (main.js).

За това направих по-долу:

Заредих JavaScript кода в HTML файла в правилния ред, първо myvariables.js, след това main.js:

 <html> <body onload="bodyReady();" > <script src="myvariables.js" > </script> <script src="main.js" > </script> <!-- Some other code --> </body> </html>