Як включити файл JavaScript в інший файл JavaScript?


5193

Чи є в JavaScript щось подібне до @importCSS, що дозволяє вам включати файл JavaScript всередині іншого файлу JavaScript?



82
@Daniel, я не хочу використовувати дзвінок AJAX.
Alec Smart

13
Чому б не оголосити імпортований файл перед іншим, який вимагає цього, просто скориставшись упорядкованими scriptтегами?
фальсарела

6
@Claudiu Це не допоможе імпортувати що- небудь, але воно також має працювати. Якщо у вас є файл JS, який залежить від іншого файлу JS, просто спочатку оголосіть теги скриптів файлів залежності, тому пізніше вже будуть завантажені його залежності. Якщо у вас є ситуація, коли це не можливий підхід, відповіді тут повинні бути корисними.
фальсарела

1
у чому полягає практична перевага цього? в будь-якому випадку база коду, залежна від файлу javascript, не збирається завантажуватись і не почне працювати, ні в якому разі вона не завантажується!
Ciasto piekarz

Відповіді:


4470

Старі версії JavaScript не мали імпорту, включали або вимагали, тому було розроблено багато різних підходів до цієї проблеми.

Але з 2015 року (ES6) у JavaScript встановлено стандарт модулів ES6 для імпорту модулів у Node.js, що також підтримується більшістю сучасних браузерів .

Для сумісності зі старими веб-переглядачами можна використовувати такі інструменти, як Webpack і Rollup та / або інструменти для транспіляції, як Babel .

Модулі ES6

Модулі ECMAScript (ES6) підтримуються в Node.js з версії 8.5, з --experimental-modulesпрапором і, принаймні, Node.js v13.8.0 без прапора. Щоб включити «ESM» ( по порівнянні з попередньою системою модуля CommonJS стилі Node.js в [ «CJS»]) або ви використовувати "type": "module"в package.jsonабо дають файли з розширенням .mjs. (Аналогічно, модулі, написані попереднім модулем CJS Node.js, можна назвати, .cjsякщо за замовчуванням встановлено ESM.)

Використання package.json:

{
    "type": "module"
}

Потім module.js:

export function hello() {
  return "Hello";
}

Потім main.js:

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

Використовуючи .mjs, у вас є module.mjs:

export function hello() {
  return "Hello";
}

Потім main.mjs:

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

Модулі ECMAScript у браузерах

Веб-браузери підтримували безпосередньо завантаження модулів ECMAScript (не потрібні такі інструменти, як Webpack), починаючи з Safari 10.1, Chrome 61, Firefox 60 та Edge 16. Перевірте поточну підтримку за допомогою каніуси . Не потрібно використовувати .mjsрозширення Node.js ; браузери повністю ігнорують розширення файлів на модулях / скриптах.

<script type="module">
  import { hello } from './hello.mjs'; // Or it could be simply `hello.js`
  hello('world');
</script>
// hello.mjs -- or it could be simply `hello.js`
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/

Динамічний імпорт у браузерах

Динамічний імпорт дозволяє сценарію завантажувати інші сценарії за необхідності:

<script type="module">
  import('hello.mjs').then(module => {
      module.hello('world');
    });
</script>

Детальніше читайте на веб- сайті https://developers.google.com/web/updates/2017/11/dynamic-import

Node.js вимагає

Старіший стиль модуля CJS, який все ще широко використовується в Node.js, - це система module.exports/require .

// mymodule.js
module.exports = {
   hello: function() {
      return "Hello";
   }
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"   

Є й інші способи, щоб JavaScript включав зовнішній вміст JavaScript у браузери, які не потребують попередньої обробки.

Завантаження AJAX

Ви можете завантажити додатковий скрипт за допомогою AJAX-дзвінка, а потім використовувати його 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 забезпечує функцію завантаження в один рядок :

$.getScript("my_lovely_script.js", function() {
   alert("Script loaded but not necessarily executed.");
});

Динамічне завантаження сценарію

Ви можете додати тег сценарію з URL-адресою сценарію в HTML. Щоб уникнути накладних витрат jQuery, це ідеальне рішення.

Сценарій може розміщуватися навіть на іншому сервері. Крім того, браузер оцінює код. <script>Тег може бути введений в будь-який веб - сторінки <head>, або вставити безпосередньо перед закриває </body>тегом.

Ось приклад того, як це могло працювати:

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: Dynamic Script Loading .

Виявлення, коли сценарій виконаний

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

Це означає, що якщо ви будете використовувати ці трюки безпосередньо, ви не зможете використати ваш щойно завантажений код наступного рядка після того, як ви попросили його завантажити , оскільки він все ще завантажується.

Наприклад: my_lovely_script.jsмістить 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

Потім ви перезавантажуєте натискання сторінки F5. І це працює! Конфуз ...

То що робити з цим?

Що ж, ви можете використовувати хак, який пропонує автор, за посиланням, яке я вам дав. Підсумовуючи це, для людей, які поспішають, він використовує подію для запуску функції зворотного дзвінка під час завантаження сценарію. Таким чином, ви можете помістити весь код за допомогою віддаленої бібліотеки у функцію зворотного виклику. Наприклад:

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

Потім ви пишете код, який хочете використовувати ПІСЛЯ сценарій завантажений у лямбда-функції :

var myPrettyCode = function() {
   // Here, do whatever you want
};

Потім ви запускаєте все це:

loadScript("my_lovely_script.js", myPrettyCode);

Зауважте, що сценарій може виконуватися після завантаження DOM або раніше, залежно від браузера та того, чи ви включили рядок script.async = false;. Існує чудова стаття про завантаження Javascript в цілому, яка обговорює це.

Злиття вихідного коду / попередня обробка

Як уже згадувалося вгорі цієї відповіді, багато розробників використовують у своїх проектах інструменти збирання / транспіляції, такі як Parcel, Webpack або Babel, що дозволяють використовувати майбутній синтаксис JavaScript, забезпечують сумісність для старих браузерів, поєднують файли, мінімізують, виконувати розбиття коду тощо.


130
Ні, але хтось із тих, хто використовує щось настільки розвинене, як Носоріг, або б не ставив цього питання.
e-satis

192
Для завершення існує третій спосіб: у певних рішеннях, коли ви керуєте обома файлами javascript, ви можете просто зробити 1 гігантський файл JavaScript, який поєднує вміст обох файлів.
Жаба

20
Не повинен "document.createElement (" my_lovely_script.js ");" у прикладі бути "document.createElement (" script ")"?
Рассел Сілва

14
Як eval відкриває двері хакам, якщо ви виконуєте свій код?
Вінс Пануччо

6
Ваша відповідь вимагає деяких змін для IE ( onreadystatechangeподія та readyStateвластивість). Крім того, динамічне завантаження скриптів не виграє від сканерів попереднього завантаження браузера. Рекомендуйте цю статтю HTML5Rocks: html5rocks.com/en/tutorials/speed/script-loading
ruhong

570

Якщо хтось шукає щось більш просунуте, спробуйте RequireJS . Ви отримаєте додаткові переваги, такі як управління залежністю, краща паралельність та уникнення дублювання (тобто завантаження сценарію не один раз).

Ви можете записати свої файли JavaScript в "модулі", а потім посилатися на них як залежності в інших сценаріях. Або ви можете використовувати RequireJS як просте рішення "перейти до цього сценарію".

Приклад:

Визначте залежності як модулі:

деякий-залежність.js

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

implemen.js - ваш "головний" файл JavaScript, який залежить від some-ovisnost.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.

...


1
@aaaidan: причина MattDmo плюс вона покладається на зовнішню бібліотеку, яка взамін покладається на прийняту відповідь.
Девід Малдер

1
Для подолання Require.js найновішим буде кутовий js, який є більш стійким і простим у використанні, а також з іншими обов'язковими та багатими функціями HTML.
Зеешан

5
-1: Ці абстракції - "деяка залежність" - справді погані, індекси додають плутанину. Я намагаюся зрозуміти, як виглядає приклад робочого коду. Якби автор надавав робочий приклад, майже будь-хто міг би адаптувати та узагальнити його під свої потреби.
Тегірі Ненаші

1
не дуже добре працює з MVC та
пакетними скриптами

1
'додати .. без необхідності перезаписувати файли JavaScript'; круто, але як саме? Кур. відповідь пропонує додати такий "вимагати" (не "Requjs"?) до основного сценарію + таке "визначити" до кожного залежного файлу, так? Але це IS переписати, так що не переписати? -ліст коду, оскільки RequireJS дозволяє файлу ea зробити глобальний defs як нормальний? -робить це? Я щойно спробував це, + (забув?) <Скрипт src = " Requjs.org/docs/release/2.2.0/comments/require.js "> </script>, а потім 'Requjs ([' GoogleDrive.com/host /..',..Sense,function(a,b) {mycode}) ': Firebug каже, що кожен залежний завантажений, АЛЕ їхні defs не визначені в моєму коді та після.
Архітектор долі

195

Насправді є спосіб завантажувати файл 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($)
{
    /*
     * $.import_js() helper (for JavaScript importing within JavaScript code).
     */
    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');

Я також зробив простий тест для цього в Example .

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

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

І відразу ж після включення included.js, то hello()функція викликається, і ви отримаєте повідомлення.

(Ця відповідь відповідає на коментар e-satis).


Я намагаюся цей метод, але не працює для мене, елемент просто не відображається в тезі head.
сайти

16
@juanpastas - використовуйте jQuery.getScript, таким чином вам не доведеться турбуватися про написання плагіна ...
MattDMo

6
Гм, згідно з цією статтею , додавання scriptелемента headпризведе до його асинхронного виконання, якщо asyncспеціально не встановлено false.
Flimm

1
Чи не повинна змінна скрипту кодувати HTML-сутності? Якщо посилання містить ", код порушиться
RedClover

1
@Flimm шановний пане, я та моя команда дякую за ваш коментар, і я особисто зобов’язаний вам пивом навіть грошей, якщо ми коли-небудь зустрінемось особисто
Alex

155

Інший спосіб, який, на мій погляд, набагато чистіший, - це зробити синхронний запит 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(); 

1
Хороше рішення, голова включає асинхронізування, на жаль, рішення Ajax працює.
Маттео Конта

17
Як згадував хтось інший, Requjs.org робить це, а також має попередній компілятор, який з'єднує файли js, щоб вони швидше завантажувалися. Ви можете перевірити це.
Аріель

2
Знайшов, що я міг би налагодити його, додавши цю директиву внизу файлу для Chrome: // @ sourceURL = view_index.js
Todd Vance,

11
на жаль, async: false тепер застаріло в jQuery. Можливо, перерва в майбутньому, тому я б уникав.
sqram

3
@katsh Ми тут не використовуємо об'єкти jqXHR. Здається, ваша цитата не створює резервну копію попереднього коментаря, вказуючи, що вона async: falseнібито застаріла. Це не так! Як зазначено у вашій цитаті, є лише пов'язані з jqXHR матеріали.
Нуль3

101

Для вас хороша новина. Дуже скоро ви зможете легко завантажити код JavaScript. Це стане стандартним способом імпорту модулів коду JavaScript і буде частиною самого основного JavaScript.

Вам просто потрібно написати, import cond from 'cond.js';щоб завантажити макрос з іменем condфайлу cond.js.

Таким чином, вам не потрібно покладатися на будь-яку рамку JavaScript, а також не потрібно чітко робити дзвінки Ajax .

Звертатися до:


12
вимагати / імпортувати на jsfile занадто довго в майбутньому. (ІМО).
rwheadon

6
@rwheadon так здається жахливим, що це не частина мови! Як js люди щось роблять, це поза мене! Я новачок у цьому, і це здається найгіршим (з багатьох) шматочків божевілля
JonnyRaa

@ jonny-leeds Навіть не маючи завантаженого модуля, JavaScript у браузері є досить гнучким, що ми можемо реалізувати бібліотеку типу RequireJS для управління нашим модулем.
Кін

8
середина 2015 року - все ще не реалізовано в жодних браузерах, developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
scape

так, ти маєш рацію. тепер я починаю відчувати себе погано :(. Ось, коли буде впроваджено у всіх браузерах, це буде чудовою функцією, вбудованою у javascript.
Imdad

96

Можна динамічно генерувати тег 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");

8
@ e-satis - Фактично, це перевага, сценарій синхронізації блокується. Коні на курси, але 9 разів на 10 ви хочете неблокуючий варіант.
annakata

@Svitlana - елементи сценарію, створені таким чином, є асинхронністю. В даний час це може розглядатися як експлуатація лазівки, тому це може бути не підтвердженням майбутнього, я не бачив нічого в жодному стандарті, який би це пояснював.
annakata

Насправді я повертаю це назад, я помітив, що ти додаєш тіло, а не голову.
annakata

@annakata: Яка різниця? BTW, yahoo пропонують додати теги скриптів до кінця тексту, тому нічого не повинно бути з цим при динамічному додаванні.
Світлана Максимчук

7
@ e-satis асинхронність хороша тим, що вона не заморожує вашу сторінку. Використовуйте зворотний дзвінок, щоб отримувати сповіщення, коли це буде зробленоjs.onload = callback;
Vitim.us

74

Заява 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;

... але на сьогоднішній день не підтримується жодним браузером, згідно таблиці сумісності на сторінці, на яку ви пов’язані.
Нуль3

6
Тепер ви можете написати код ES6 і компілювати його з Babel.js ( babeljs.io ) у будь-яку бажану систему поточного модуля (CommonJS / AMD / UMD): babeljs.io/docs/usage/modules
Джеремі Гарріс

@ Zero3 Мабуть, новий IE (Edge) єдиний
Julian Avar

у 2019 році IE досі не підтримує це в будь-якій формі. Чому мікрософт повинен бути таким проти використання?
GreySage

61

Можливо, ви можете скористатися цією функцією, яку я знайшов на цій сторінці Як я включаю файл 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)
}

5
Слід корисно додатиscript.onload = callback;
Vitim.us

@SvitlanaMaksymchuk значить, якщо я не використовую var, змінна буде глобальною?
Франциско Корралес Моралес

@FranciscoCorrales так.
Крістофер Чіче

Це закінчується в глобальному масштабі з
варом


54

Ось синхронна версія без 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заголовок у своїй відповіді.


Відмінна функція! Завантажує JavaScript перед тим, як після корпусу буде записаний додатковий JS. Дуже важливо при завантаженні декількох сценаріїв.
tfont

3
@heinob: Що я можу зробити, щоб він працював для міждоменного домену? (сценарій завантаження з http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js)
користувач2284570

@ user2284570: Якщо ви є власником закордонного домену: у відповідь сервера встановіть заголовок "дозволити походження". Якщо ви не власник: нічого. Вибачте! Це політика перехресного походження.
heinob

2
@ user2284570: Я розумію ваш коментар таким чином, що ви не власник домену, з якого ви хочете завантажити скрипт. У такому випадку ви можете завантажити сценарій лише через вставлений <script>тег, а не через XMLHttpRequest.
heinob

2
Для тих, хто планує використовувати це у Firefox (скажімо для сценаріїв зображень), додайте цей рядок у верхню частину файлу:const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1");
Kwestion

49

Я щойно написав цей код 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 () {
        /* Use foo.js and bar.js here */
    });
</script>

Суть: http://gist.github.com/284442 .


7
jrburke написав це як RequireJS. Github: Requjs.org/docs/requirements.html
Майк Карон

Це не ставить завантажений скрипт за межі області, де виклик вимагає ()? Здається, що eval () - єдиний спосіб зробити це в межах сфери. Або є інший шлях?
trusktr

44

Ось узагальнена версія того, як Facebook робить це для своєї всюдисущої кнопки «Like»:

<script>
  var firstScript = document.getElementsByTagName('script')[0],
      js = document.createElement('script');
  js.src = 'https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js';
  js.onload = function () {
    // do stuff with your dynamically loaded script
    snowStorm.snowColor = '#99ccff';
  };
  firstScript.parentNode.insertBefore(js, firstScript);
</script>

Якщо він працює для Facebook, він буде працювати для вас.

Причина, чому ми шукаємо перший scriptелемент замість цього, headабо bodyце те, що деякі веб-переглядачі не створюють його, якщо він відсутній, але ми гарантовано матимемо scriptелемент - цей. Детальніше читайте на веб- сайті http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ .


3
Чорт приємний! Деякі методи тут також працюють, але при динамічній установці це працює найкраще.
tfont

Я продовжив ваш сценарій, щоб усунути дублікат
Каміль Домбровський

39

Якщо ви хочете в чистому JavaScript, ви можете використовувати document.write .

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

Якщо ви використовуєте бібліотеку jQuery, ви можете використовувати $.getScriptметод.

$.getScript("another_script.js");

8
не вдасться document.write видалити все інше?
Ейза Аділь

30

Ви також можете зібрати свої сценарії за допомогою 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

16
Здається, суть у тому, щоб тримати це все в JavaScript на передньому кінці
Аріель

1
Дякуємо, що нагадали про це. Ви також можете мати теги для запису PHP <script> у своєму заголовку HTML, щоб файли js, які вам потрібні (і лише ті), будуть завантажені.
Рольф

29

Більшість показаних тут рішень передбачають динамічне завантаження. Я шукав замість цього компілятор, який збирає всі залежні файли в єдиний вихідний файл. Те саме, що і препроцесори Less / Sass мають справу з 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 / Форма / Введення / 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(){}
    }
};

2
З цієї посади я придумав набагато краще рішення - компілятор модулів CommonJS - github.com/dsheiko/cjsc Отже, ви можете просто написати CommonJs або NodeJs модулі та отримати доступ один до одного, зберігаючи їх у відокремлених межах. Переваги: ​​Немає необхідності в декількох HTTP-запитах, які впливають на продуктивність. Вам не потрібно вручну загортати код модуля - це відповідальність компілятора (тому краща читабельність вихідного коду). Вам не потрібні зовнішні бібліотеки. Він сумісний з UMD- та модулі NodeJs (наприклад, ви можете адресувати jQuery, Backbone як модулі, не торкаючись їх коду)
Дмитро Шейко

26

Якщо ваш намір завантажити файл 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>

22

Це слід зробити:

xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);

5
те eval, що з цим не так. Від Крокфорда , " evalє злом. Ця evalфункція є найбільш зловживаною функцією JavaScript. Уникайте цього. evalМає псевдоніми. Не використовуйте Functionконструктор. Не передайте рядки до setTimeoutабо setInterval". Якщо ви ще не прочитали його "JavaScript: хороші частини", тоді вийдіть і зробіть це прямо зараз. Ви будете не пошкодуєте про це.
MattDMo

13
@MattDMo "Хтось сказав, що це погано" насправді не є аргументом.
Кейсі

4
@emodendroket Я вважаю, ви не знаєте, хто такий Дуглас Крокфорд .
MattDMo

13
@MattDMo Я повністю усвідомлюю, хто він, але він людина, а не бог.
Кейсі

2
@tggagne: Що я можу зробити, щоб він працював для міждоменного домену? (сценарій завантаження з http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js)
user2284570

21

Або замість того, щоб включати під час виконання, використовуйте сценарій для об'єднання перед завантаженням.

Я використовую зірочки (не знаю, чи є інші). Ви будуєте свій код JavaScript в окремих файлах і включаєте коментарі, які обробляються движком Sprockets як включене. Для розробки ви можете включати файли послідовно, а потім для виробництва для їх об'єднання ...

Дивись також:


Browrify набагато популярніший, ніж Зірочки.
Дан Даскалеску

18

У мене було просте питання, але мене збентежили відповіді на це питання.

Мені довелося використовувати змінну (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>

Файл: myvariables.js

var myVar1 = "I am variable from myvariables.js";

Файл: main.js

// ...
function bodyReady() {
    // ...
    alert (myVar1);    // This shows "I am variable from myvariables.js", which I needed
    // ...
}
// ...

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

Це врятувало мені день. Я сподіваюся, що це допомагає.


Проблема з цією відповіддю полягає в тому, що це не щось подібне import. Вам потрібен HTML-файл, щоб передати матеріали з одного js-файлу в інший.
Каніцид

Дуже правильно. Ось, що деякі інші відповіді мають це як рішення. Однак у мене було два файли JS, один повинен використовувати інші змінні JS. Немає node.js, next.js, express.js тощо, тому імпорт АБО не потребує роботи, просто були звичайні файли .js.
Манохар Редді Поредді

Зрозуміло, однак, питання насправді просить імпортувати файл JavaScript в інший файл, а не просто отримувати доступ до його змінних за допомогою HTML-файлу. Наприклад, припустимо, що ви створюєте функціональність для кнопки, і ви використовуєте три різні файли js, один для обробки кліків, один для обробки наведення курсором, один для зворотних викликів для кожного з двох інших. Було б корисно імпортувати інші два js у сам третій js та мати лише один <script>тег. Це може допомогти в організації. Ця відповідь просто не те, про що запитували, і не є ідеальною в цьому контексті.
Cannicide

Коли я шукав рішення своєї проблеми, я шукав правильний шлях, проте Google вважає, що це правильна сторінка, тому я приземлився тут. Ось чому я написав тут свою відповідь. Схоже, я зробив правильно, через 15 оновлених нагород. Щоб не гаяти часу інших людей, я поставив чітке початок того, що мій сценарій - ставте перший код HTML - що, схоже, допомогло, оскільки ви відповіли та сказали, що html - це не ваш сценарій. Сподіваюся, що прояснилося.
Манохар Редді Поредді

Так - насправді схоже, що деякі люди шукали дещо іншу проблему, для якої це рішення, і знайшли це. Хоча це необов'язково відповідь на це питання, це, безумовно, відповідь на інше, подібне питання. Таким чином, цілком відповісти на цю відповідь тут, оскільки це допомагає тим, хто шукав цю відповідь. Дякую за цю відповідь, що пояснила це.
Cannicide

16

Якщо ви використовуєте веб-робітників і хочете включити додаткові сценарії в область роботи працівника, інші відповіді щодо додавання сценаріїв до headтегу тощо не будуть працювати для вас.

На щастя, Web Workers мають власну importScriptsфункцію, яка є глобальною функцією в області Web Worker, яка є власною для самого браузера, оскільки вона є частиною специфікації .

Крім того, як підкреслюється другий найвищий відповідь на ваше запитання , RequireJS також може обробляти, включаючи сценарії всередині Web Worker (ймовірно, дзвонить importScriptsсобі, але з кількома іншими корисними функціями).


16

Сучасною мовою з перевіркою, чи сценарій уже завантажений, було б:

function loadJs(url){
  return new Promise( (resolve, reject) => {
    if (document.querySelector(`head > script[src="${src}"]`) !== null) return resolve()
    const script = document.createElement("script")
    script.src = url
    script.onload = resolve
    script.onerror = reject
    document.head.appendChild(script)
  });
}

Використання (асинхронізація / очікування):

try { await loadJs("https://.../script.js") } 
catch(error) {console.log(error)}

або

await loadJs("https://.../script.js").catch(err => {})

Використання (Обіцянка):

loadJs("https://.../script.js").then(res => {}).catch(err => {})

Приємно. Гарне рішення.
Naftali aka Neal

Короткий і потребує лише ES5, і витончено уникає формального зворотного дзвінка. Дякую Дмитре!
Еврика

Нічого собі, працює в браузері без сервера. pi.js = просто var pi = 3.14. викликати функцію loadJS () черезloadJs("pi.js").then(function(){ console.log(pi); });
zipzit

14

@importСинтаксис для досягнення CSS-подібний JavaScript імпортування можна з допомогою такого інструменту, як суміші через їх особливий .mixтип файлу (див тут ). Я думаю, що програма просто використовує один із вищезгаданих методів узагалі, хоча я не знаю.

З документації на суміші на .mixфайли:

Змішувати файли - просто .js або .css файли з .mix. у назві файлу. Файл міксу просто розширює функціональність нормального стилю або файлу сценарію та дозволяє імпортувати та комбінувати.

Ось приклад .mixфайлу, який поєднує кілька .jsфайлів в один:

// scripts-global.mix.js
// Plugins - Global

@import "global-plugins/headroom.js";
@import "global-plugins/retina-1.1.0.js";
@import "global-plugins/isotope.js";
@import "global-plugins/jquery.fitvids.js";

Суміш виводить це як scripts-global.jsі, як мінімізовану версію ( scripts-global.min.js).

Примітка: я жодним чином не пов’язаний із сумішшю, окрім того, що використовую її як інструмент розробки. Я натрапив на це питання, побачивши.mix файл JavaScript у дії (на одній із котельних плит суміші) і трохи збентежений ним ("ви можете це зробити?", Подумав я собі). Тоді я зрозумів, що це специфічний для файлу тип файлу (дещо розчаровує, погодився). Тим не менш, зрозуміли, що ці знання можуть бути корисними для інших.

ОНОВЛЕННЯ : Суміш тепер безкоштовна (офлайн).

ОНОВЛЕННЯ : Тепер суміш відмінено. Старі випуски сумішей ще доступні


Це було б дивним, якби це модуль вузла.
b01

@ b01 Звучить як виклик;) Якби я тільки мав час ... можливо, хтось ще робить?
Ісаак Грегсон


13

Мій звичайний метод:

var require = function (src, cb) {
    cb = cb || function () {};

    var newScriptTag = document.createElement('script'),
        firstScriptTag = document.getElementsByTagName('script')[0];
    newScriptTag.src = src;
    newScriptTag.async = true;
    newScriptTag.onload = newScriptTag.onreadystatechange = function () {
        (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') && (cb());
    };
    firstScriptTag.parentNode.insertBefore(newScriptTag, firstScriptTag);
}

Він чудово працює і не використовує для мене перезавантаження сторінок. Я спробував метод AJAX (одна з інших відповідей), але він, здається, не так добре працює для мене.

Ось пояснення того, як працює код для тих, хто цікавиться: по суті, він створює новий тег сценарію (після першого) URL-адреси. Він встановлює його в асинхронний режим, тому він не блокує решту коду, а викликає зворотний виклик, коли ReadyState (стан завантаженого вмісту) змінюється на 'завантажений'.


13

Хоча ці відповіді чудові, є просте "рішення", яке існувало з моменту завантаження сценарію, і воно охопить 99,999% випадків використання більшості людей. Просто включіть потрібний вам сценарій перед тим, хто його вимагає. Для більшості проектів не потрібно багато часу, щоб визначити, які сценарії потрібні та в якому порядку.

<!DOCTYPE HTML>
<html>
    <head>
        <script src="script1.js"></script>
        <script src="script2.js"></script>
    </head>
    <body></body>
</html>

Якщо script2 вимагає script1, це дійсно абсолютний найпростіший спосіб зробити щось подібне. Я дуже здивований, що ніхто цього не підніс, оскільки це є найбільш очевидною і найпростішою відповіддю, яка застосовуватиметься майже в кожному окремому випадку.


1
Я здогадуюсь для багатьох людей, включаючи мене, нам потрібне ім’я динамічного файлу.
Стюарт Макінтайр

1
@StuartMcIntyre у цьому випадку встановіть атрибут src тегу сценарію під час виконання та дочекайтеся події завантаження (звичайно, в цьому випадку є кращі рішення у 2019 році).
KthProg

12

Я написав простий модуль, який автоматизує завдання імпорту / включення скриптів модулів у JavaScript. Для детального пояснення коду, зверніться до публікації блогу JavaScript вимагають / імпортують / включають модулі .

// ----- USAGE -----

require('ivar.util.string');
require('ivar.net.*');
require('ivar/util/array.js');
require('http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');

ready(function(){
    //Do something when required scripts are loaded
});

    //--------------------

var _rmod = _rmod || {}; //Require module namespace
_rmod.LOADED = false;
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
    scripts: {},
    length: 0
};

_rmod.findScriptPath = function(script_name) {
    var script_elems = document.getElementsByTagName('script');
    for (var i = 0; i < script_elems.length; i++) {
        if (script_elems[i].src.endsWith(script_name)) {
            var href = window.location.href;
            href = href.substring(0, href.lastIndexOf('/'));
            var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
            return url.substring(href.length+1, url.length);
        }
    }
    return '';
};

_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark
                                                   //the root directory of your library, any library.


_rmod.injectScript = function(script_name, uri, callback, prepare) {

    if(!prepare)
        prepare(script_name, uri);

    var script_elem = document.createElement('script');
    script_elem.type = 'text/javascript';
    script_elem.title = script_name;
    script_elem.src = uri;
    script_elem.async = true;
    script_elem.defer = false;

    if(!callback)
        script_elem.onload = function() {
            callback(script_name, uri);
        };
    document.getElementsByTagName('head')[0].appendChild(script_elem);
};

_rmod.requirePrepare = function(script_name, uri) {
    _rmod.loading.scripts[script_name] = uri;
    _rmod.loading.length++;
};

_rmod.requireCallback = function(script_name, uri) {
    _rmod.loading.length--;
    delete _rmod.loading.scripts[script_name];
    _rmod.imported[script_name] = uri;

    if(_rmod.loading.length == 0)
        _rmod.onReady();
};

_rmod.onReady = function() {
    if (!_rmod.LOADED) {
        for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
            _rmod.on_ready_fn_stack[i]();
        });
        _rmod.LOADED = true;
    }
};

_.rmod = namespaceToUri = function(script_name, url) {
    var np = script_name.split('.');
    if (np.getLast() === '*') {
        np.pop();
        np.push('_all');
    }

    if(!url)
        url = '';

    script_name = np.join('.');
    return  url + np.join('/')+'.js';
};

//You can rename based on your liking. I chose require, but it
//can be called include or anything else that is easy for you
//to remember or write, except "import", because it is reserved
//for future use.
var require = function(script_name) {
    var uri = '';
    if (script_name.indexOf('/') > -1) {
        uri = script_name;
        var lastSlash = uri.lastIndexOf('/');
        script_name = uri.substring(lastSlash+1, uri.length);
    } 
    else {
        uri = _rmod.namespaceToUri(script_name, ivar._private.libpath);
    }

    if (!_rmod.loading.scripts.hasOwnProperty(script_name)
     && !_rmod.imported.hasOwnProperty(script_name)) {
        _rmod.injectScript(script_name, uri,
            _rmod.requireCallback,
                _rmod.requirePrepare);
    }
};

var ready = function(fn) {
    _rmod.on_ready_fn_stack.push(fn);
};

10

Цей скрипт додасть файл JavaScript у верхній частині будь-якого іншого <script>тегу:

(function () {
    var li = document.createElement('script'); 
    li.type = 'text/javascript'; 
    li.src= "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"; 
    li.async=true; 
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(li, s);
})();

10

Існує також Head.js . З цим дуже легко впоратися:

head.load("js/jquery.min.js",
          "js/jquery.someplugin.js",
          "js/jquery.someplugin.css", function() {
  alert("Everything is ok!");
});

Як бачите, це простіше, ніж Require.js і так само зручно, як $.getScriptметод jQuery . Він також має деякі вдосконалені функції, такі як умовне завантаження, виявлення функцій та багато іншого .


10

На це питання існує багато потенційних відповідей. Моя відповідь, очевидно, ґрунтується на ряді їх. Це я закінчив, прочитавши всі відповіді.

Проблема з $.getScript і справді будь-яке інше рішення, яке вимагає зворотного дзвінка, коли завантаження завершено, полягає в тому, що якщо у вас є кілька файлів, які використовують його і залежать один від одного, у вас більше немає способу дізнатися, коли всі сценарії завантажені (як тільки вони вкладені у кількох файлах).

Приклад:

file3.js

var f3obj = "file3";

// Define other stuff

file2.js:

var f2obj = "file2";
$.getScript("file3.js", function(){

    alert(f3obj);

    // Use anything defined in file3.
});

file1.js:

$.getScript("file2.js", function(){
    alert(f3obj); //This will probably fail because file3 is only guaranteed to have loaded inside the callback in file2.
    alert(f2obj);

    // Use anything defined in the loaded script...
});

Ви праві, коли говорите, що можете вказати Ajax для запуску синхронно або використовувати XMLHttpRequest , але, як видається, поточна тенденція полягає у знеціненні синхронних запитів, тому ви не можете отримати повну підтримку браузера зараз або в майбутньому.

Ви можете спробувати використати $.whenдля перевірки масиву відкладених об'єктів, але тепер ви робите це у кожному файлі, і файл2 вважатиметься завантаженим, як тільки $.whenвиконується не під час виконання зворотного виклику, тому file1 все ще продовжує виконання до завантаження file3 . У цьому справді є та сама проблема.

Я вирішив піти назад, а не вперед. Дякую document.writeln. Я знаю, що це табу, але за умови правильного використання це працює добре. Ви закінчуєте код, який можна легко налагодити, показує в DOM правильно і може забезпечити порядок залежностей завантажений правильно.

Ви, звичайно, можете використовувати $ ("body"). Append (), але тоді ви більше не зможете правильно налагоджувати.

ПРИМІТКА: Ви повинні використовувати це лише під час завантаження сторінки, інакше у вас з’явиться порожній екран. Іншими словами, завжди розміщуйте це перед / поза документом . Я не перевіряв це за допомогою після завантаження сторінки у події натискання чи чогось подібного, але я впевнений, що вона вийде з ладу.

Мені сподобалася ідея розширити jQuery, але очевидно, що вам цього не потрібно.

Перед тим, як зателефонувати document.writeln, він перевіряє, чи не завантажився сценарій, оцінивши всі елементи сценарію.

Я припускаю, що сценарій не виконується повністю, поки його document.readyподія не буде виконана. (Я знаю, що використовувати document.readyйого не потрібно, але багато людей використовують його, і поводження з цим є захисним засобом.)

Після завантаження додаткових файлів document.readyзворотні дзвінки виконуватимуться в неправильному порядку. Для вирішення цього питання, коли сценарій фактично завантажений, сценарій, який його імпортував, реімпортується сам, а виконання зупиняється. Це призводить до того, що вихідний файл тепер має document.readyвиконувати зворотний виклик після будь-якого з будь-яких сценаріїв, які імпортує.

Замість такого підходу ви можете спробувати змінити jQuery readyList, але це здавалося гіршим рішенням.

Рішення:

$.extend(true,
{
    import_js : function(scriptpath, reAddLast)
    {
        if (typeof reAddLast === "undefined" || reAddLast === null)
        {
            reAddLast = true; // Default this value to true. It is not used by the end user, only to facilitate recursion correctly.
        }

        var found = false;
        if (reAddLast == true) // If we are re-adding the originating script we do not care if it has already been added.
        {
            found = $('script').filter(function () {
                return ($(this).attr('src') == scriptpath);
            }).length != 0; // jQuery to check if the script already exists. (replace it with straight JavaScript if you don't like jQuery.
        }

        if (found == false) {

            var callingScriptPath = $('script').last().attr("src"); // Get the script that is currently loading. Again this creates a limitation where this should not be used in a button, and only before document.ready.

            document.writeln("<script type='text/javascript' src='" + scriptpath + "'></script>"); // Add the script to the document using writeln

            if (reAddLast)
            {
                $.import_js(callingScriptPath, false); // Call itself with the originating script to fix the order.
                throw 'Readding script to correct order: ' + scriptpath + ' < ' + callingScriptPath; // This halts execution of the originating script since it is getting reloaded. If you put a try / catch around the call to $.import_js you results will vary.
            }
            return true;
        }
        return false;
    }
});

Використання:

Файл3:

var f3obj = "file3";

// Define other stuff
$(function(){
    f3obj = "file3docready";
});

Файл2:

$.import_js('js/file3.js');
var f2obj = "file2";
$(function(){
    f2obj = "file2docready";
});

Файл1:

$.import_js('js/file2.js');

// Use objects from file2 or file3
alert(f3obj); // "file3"
alert(f2obj); // "file2"

$(function(){
    // Use objects from file2 or file3 some more.
    alert(f3obj); //"file3docready"
    alert(f2obj); //"file2docready"
});

Саме так стверджується прийнята на даний момент відповідь: просто недостатньо.
Cannicide

Основна відмінність полягає в тому, що якщо відсутня залежність, вона додасть тег скрипту для залежності, а також додасть тег скрипту для викличного файлу та видалить помилку, яка зупиняє виконання. Це спричиняє обробку та запуск сценаріїв у правильному порядку та усуває необхідність зворотного зв'язку. Так залежний скрипт буде завантажений і виконаний перед викликовим сценарієм, підтримуючи вкладення.
curlyhairedgenius

Щодо "поточної тенденції, як видається, знецінення синхронних запитів", це справедливо лише тому, що багато розробників неправомірно їх зловживали та змушували користувачів чекати без потреби. Однак якщо запит є природно синхронним, як-от заява Включити, то простий синхронний Ajax просто чудовий. Я створив загальну функцію розширення JavaScript, яка синхронно виконує такі функції, як читання файлу, що не є частиною JavaScript, запустивши файл «сервер» PHP, і вважаю це дуже корисним під час написання програм за допомогою JavaScript. Для такого Ajax не потрібен локальний веб-сервер.
Девід Спектор

10

Існує кілька способів реалізації модулів у Javascript. Ось два найпопулярніших:

Модулі ES6

Браузери ще не підтримують цю модульну модуль, тому для того, щоб використовувати цей синтаксис, потрібно використовувати такий пакет, як webpack. Використовувати пакетний пакет краще все-таки, оскільки це може об'єднати всі ваші різні файли в один (або пару пов'язаних) файлів. Це обслуговуватиме файли з сервера до клієнта швидше, оскільки кожен запит HTTP має додані додаткові накладні витрати. Таким чином, зменшуючи загальний HTTP-запит, ми покращуємо продуктивність. Ось приклад модулів ES6:

// main.js file

export function add (a, b) {
  return a + b;
}

export default function multiply (a, b) {
  return a * b;
}


// test.js file

import {add}, multiply from './main';   // for named exports between curly braces {export1, export2}
                                        // for default exports without {}

console.log(multiply(2, 2));  // logs 4

console.log(add(1, 2));  // logs 3

CommonJS (використовується в NodeJS)

Ця модульна система використовується в NodeJS. Ви в основному додаєте свій експорт до об'єкта, який називається module.exports. Потім ви можете отримати доступ до цього об’єкта через require('modulePath'). Тут важливо усвідомити, що ці модулі кешуються, тому якщо ви require()встановите певний модуль двічі, він поверне вже створений модуль.

// main.js file

function add (a, b) {
  return a + b;
}

module.exports = add;  // here we add our add function to the exports object


// test.js file

const add = require('./main'); 

console.log(add(1,2));  // logs 3

9

Я прийшов до цього питання, тому що шукав простий спосіб підтримати колекцію корисних плагінів JavaScript. Побачивши тут деякі рішення, я придумав таке:

  1. Налаштуйте файл під назвою "plugins.js" (або extensions.js або що завгодно). Зберігайте свої плагінні файли разом з одним головним файлом.

  2. plugins.js матиме масив під назвою, pluginNames[]який ми повторимо each(), а потім додаємо <script>тег до голови до кожного плагіна

//set array to be updated when we add or remove plugin files
var pluginNames = ["lettering", "fittext", "butterjam", etc.];

//one script tag for each plugin
$.each(pluginNames, function(){
    $('head').append('<script src="js/plugins/' + this + '.js"></script>');
});
  1. Вручну зателефонуйте лише в один файл у голові:
    <script src="js/plugins/plugins.js"></script>

АЛЕ:

Незважаючи на те, що всі плагіни потрапляють у тег заголовка так, як вони повинні, вони не завжди запускаються веб-переглядачем при натисканні на сторінку або оновлення.

Я виявив, що надійніше просто писати теги сценарію в PHP include. Вам потрібно написати лише один раз, і це така ж робота, як і виклик плагіна за допомогою JavaScript.


@will, ваше рішення виглядає набагато чистішим, ніж моє, і я переживаю, що у мене можуть виникнути помилки, якщо я використовую моє, оскільки воно використовує .append (). Отже, щоб скористатися цією функцією, ви можете просто зателефонувати до цієї функції один раз для кожного файла плагіна, який ви хочете включити?
rgb_life
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.