it-swarm.com.ru

Как включить файл JavaScript в другой файл JavaScript?

Есть ли в JavaScript что-то похожее на @import в CSS, которое позволяет включать файл JavaScript в другой файл JavaScript?

4481
Alec Smart

В старых версиях JavaScript не было импорта, включения или требования, поэтому было разработано много разных подходов к этой проблеме.

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

Для совместимости со старыми браузерами можно использовать инструменты build и/или transpilation .

ES6 Модули

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

// module.mjs
export function hello() {
  return "Hello";
}
// 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 ,.

<script type="module">
  import { hello } from './hello.mjs';
  hello('world');
</script>
// hello.mjs
export function hello(text) {
  const div = document.createElement('div');
  div.textContent = `Hello ${text}`;
  document.body.appendChild(div);
}

Узнайте больше на 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 требует

Старый стиль импорта модулей, все еще широко используемый в 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 внешнего содержимого в браузерах, которые не требуют предварительной обработки.

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

Динамическая загрузка скриптов

Вы можете добавить тег HTML с 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, обеспечивать обратную совместимость для старых браузеров, объединять файлы, минимизировать, выполнять разбиение кода и т. д.

4044
e-satis

Если кто-то ищет что-то более продвинутое, попробуйте RequireJS . Вы получите дополнительные преимущества, такие как управление зависимостями, лучший параллелизм и избежание дублирования (то есть получение сценария более одного раза).

Вы можете записать свои файлы JavaScript в «модули», а затем ссылаться на них как на зависимости в других скриптах. Или вы можете использовать RequireJS как простое решение «иди и получи этот скрипт».

Пример:

Определите зависимости как модули:

some-dependency.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
});

creation.js - это ваш «основной» файл JavaScript, который зависит от some-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, а также более определенные модули. Он оптимизирован для использования в браузере, в том числе в Интернете Рабочий, но его можно использовать в других средах JavaScript, например Носорог и Узел Он реализует API асинхронного модуля.

RequireJS использует простые теги сценариев для загрузки модулей/файлов, поэтому он должен Позвольте для легкой отладки. Его можно использовать просто для загрузки существующих Файлы JavaScript, поэтому вы можете добавить его в существующий проект без необходимость переписать ваши файлы JavaScript.

... 

533
John Strickler

На самом деле это способ загрузить файл JavaScript not асинхронно, так что вы можете использовать функции, включенные в только что загруженный файл, сразу после загрузки, и я думаю, что он работает во всех браузерах.

Вам необходимо использовать jQuery.append() в элементе <head> вашей страницы, то есть:

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

Однако этот метод также имеет проблему: если в импортированном файле JavaScript возникает ошибка, Firebug (а также Firefox Error Console и Chrome Developer Tools также) сообщат о своем месте неверно, что является большая проблема, если вы используете 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');

Я также сделал простой тест для этого в Пример .

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

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

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

(Этот ответ является ответом на комментарий e-sat).

173
Kipras

Другой способ, который, на мой взгляд, намного чище, - это сделать синхронный 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);
        }
    });
}

Затем вы можете использовать его в своем коде, как если бы вы обычно использовали include:

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

И сможете вызвать функцию из необходимого скрипта в следующей строке:

subscript.doSomethingCool(); 
138
Ariel

Для вас есть хорошие новости. Очень скоро вы сможете легко загрузить код JavaScript. Это станет стандартным способом импорта модулей кода JavaScript и станет частью самого ядра JavaScript. 

Вам просто нужно написать import cond from 'cond.js'; для загрузки макроса с именем cond из файла cond.js.

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

Ссылаться на:

90
Imdad

Можно динамически генерировать тег 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");
79
Svitlana Maksymchuk

Заявление 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;
62
draupnie

Может быть, вы можете использовать эту функцию, которую я нашел на этой странице Как включить файл 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
Arnaud Gouder de Beauregard

Вот синхронный версия без 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
heinob

Я только что написал этот код JavaScript (используя Prototype for 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 .

43
nornagon

Вот обобщенная версия того, как Facebook делает это для их вездесущей кнопки «Нравится»:

<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/ .

36
Dan Dascalescu

Если вы хотите использовать чистый JavaScript, вы можете использовать document.write.

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

Если вы используете библиотеку jQuery, вы можете использовать метод $.getScript.

$.getScript("another_script.js");
31
Venu immadi

Вы также можете собрать свои скрипты, используя 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
Calmarius

Большинство представленных здесь решений предполагают динамическую загрузку. Вместо этого я искал компилятор, который собирает все зависимые файлы в один выходной файл. Так же, как 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/Form/Input/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
Dmitry Sheiko

Если вы намерены загрузить файл 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
Adem İlhan

Это должно сделать:

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

Или вместо включения во время выполнения используйте сценарий для объединения перед загрузкой.

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

Смотрите также:

17
JMawer

Если вы используете Web Workers и хотите включить в область работника дополнительные сценарии, другие ответы о добавлении сценариев в тег head и т.д. Не будут работать для вас.

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

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

14
Turnerj

У меня была простая проблема, но я был озадачен ответами на этот вопрос.

Мне пришлось использовать переменную (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 автоматически.

Это спасло мой день. Надеюсь, это поможет.

13
Manohar Reddy Poreddy

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

Из документации Mixture по файлам .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";

Mixture выводит это как scripts-global.js, а также как уменьшенную версию (scripts-global.min.js).

Примечание: я никоим образом не связан с Mixture, кроме как использовать его в качестве инструмента разработки переднего плана. Я столкнулся с этим вопросом, увидев файл .mix JavaScript в действии (в одном из шаблонов Mixture) и будучи немного смущенным этим («Вы можете сделать это?» - подумал я про себя). Затем я понял, что это тип файла для приложения (несколько разочаровывающий, согласился). Тем не менее, полагал, что знания могут быть полезны для других.

UPDATE: смесь является теперь бесплатной (не в сети).

UPDATE: Смесь теперь снята с производства. Старые релизы смеси все еще доступны

12
Isaac Gregson

Мой обычный метод:

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 (состояние загружаемого содержимого) меняется на «загружен».

11
Christopher Dumas

Я написал простой модуль, который автоматизирует работу по импорту/включению скриптов модуля в JavaScript. Подробное описание кода см. В сообщении в блоге JavaScript require/import/include modules.

// ----- 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);
};
11
stamat
var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);
10
Sam4Code

На современном языке это было бы 

function loadJs( url ){
  return new Promise( resolve => {
    const script = document.createElement( "script" );
    script.src = url;
    script.onload = resolve;
    document.head.appendChild( script );
  });
}
10
Dmitry Sheiko

Также есть 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. Он также имеет некоторые расширенные функции, такие как условная загрузка, обнаружение функций и намного больше .

9
Ale

Я пришел к этому вопросу, потому что искал простой способ поддерживать коллекцию полезных плагинов JavaScript. Увидев некоторые решения здесь, я придумал это:

  1. Настройте файл с именем «plugins.js» (или extensions.js или что у вас есть). Храните ваши файлы плагинов вместе с этим одним основным файлом.

  2. plugins.js будет иметь массив с именем «pluginNames []», который мы будем повторять для каждого (), , а затем добавлять тег к заголовку для каждого плагина.

    // установить массив для обновления при добавлении или удалении файлов плагинов var pluginNames = ["lettering", "fittext", "butterjam" и т. д.]; // один тег сценария для каждого плагина $ .each (pluginNames, function () { $ ('head'). append (''); });

  3. вручную вызовите только один файл в вашей голове:
    <script src="js/plugins/plugins.js"></script>

Я обнаружил, что, хотя все плагины вставлялись в тег head так, как они должны, они не всегда запускались браузером при нажатии на страницу или обновлении.

Я обнаружил, что более надежно просто написать теги сценария в PHP include. Вы должны написать это только один раз, и это такая же работа, как вызов плагина с использованием JavaScript.

9
rgb_life

Этот скрипт добавит файл 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);
})();
9
Vicky Gonsalves

Есть много потенциальных ответов на этот вопрос. Мой ответ, очевидно, основан на ряде из них. Это то, чем я закончил, прочитав все ответы.

Проблема с $.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 для проверки массива отложенных объектов, но теперь вы делаете это в каждом файле, и file2 будет считаться загруженным, как только $.when будет выполнен, а не при выполнении обратного вызова, поэтому file1 все еще продолжает выполнение до file3 загружен. Это действительно до сих пор та же проблема.

Я решил идти назад, а не вперед. Спасибо document.writeln. Я знаю, что это табу, но при правильном использовании это работает хорошо. Вы получите код, который можно легко отладить, правильно отобразить в DOM и убедиться, что зависимости загружены правильно.

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

ПРИМЕЧАНИЕ. Вы должны использовать это только во время загрузки страницы, в противном случае вы получите пустой экран. Другими словами, всегда помещайте это перед/за пределами document.ready. Я не проверял использование этого после загрузки страницы в событии щелчка или чем-то подобном, но я почти уверен, что это потерпит неудачу.

Мне понравилась идея расширения 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;
    }
});

Использование:

File3:

var f3obj = "file3";

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

File2:

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

File1:

$.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"
});
8
curlyhairedgenius

Я создал функцию, которая позволит вам использовать словоблудие, аналогичное C #/Java, для включения файла JavaScript. Я немного протестировал его даже внутри another файла JavaScript, и, похоже, он работает. Это требует jQuery, хотя для немного "магии" в конце.

Я поместил этот код в файл в корне моего каталога скриптов (я назвал его global.js, но вы можете использовать все, что захотите. Если я не ошибаюсь, и jQuery должен быть единственными необходимыми скриптами на данной странице. Имейте в виду, это в значительной степени непроверено за пределами некоторого базового использования, поэтому могут возникнуть или не возникнуть какие-либо проблемы с тем, как я это сделал, используйте на свой страх и риск yadda yadda Я не несу ответственности, если вы что-то испортили yadda yadda:

/**
* @fileoverview This file stores global functions that are required by other libraries.
*/

if (typeof(jQuery) === 'undefined') {
    throw 'jQuery is required.';
}

/** Defines the base script directory that all .js files are assumed to be organized under. */
var BASE_DIR = 'js/';

/**
* Loads the specified file, outputting it to the <head> HTMLElement.
*
* This method mimics the use of using in C# or import in Java, allowing
* JavaScript files to "load" other JavaScript files that they depend on
* using a familiar syntax.
*
* This method assumes all scripts are under a directory at the root and will
* append the .js file extension automatically.
*
* @param {string} file A file path to load using C#/Java "dot" syntax.
*
* Example Usage:
* imports('core.utils.extensions');
* This will output: <script type="text/javascript" src="/js/core/utils/extensions.js"></script>
*/
function imports(file) {
    var fileName = file.substr(file.lastIndexOf('.') + 1, file.length);

    // Convert PascalCase name to underscore_separated_name
    var regex = new RegExp(/([A-Z])/g);
    if (regex.test(fileName)) {
        var separated = fileName.replace(regex, ",$1").replace(',', '');
        fileName = separated.replace(/[,]/g, '_');
    }

    // Remove the original JavaScript file name to replace with underscore version
    file = file.substr(0, file.lastIndexOf('.'));

    // Convert the dot syntax to directory syntax to actually load the file
    if (file.indexOf('.') > 0) {
        file = file.replace(/[.]/g, '/');
    }

    var src = BASE_DIR + file + '/' + fileName.toLowerCase() + '.js';
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;

    $('head').find('script:last').append(script);
}
7
Wayne Molina

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

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

Если script2 требует script1, это действительно самый простой способ сделать что-то подобное. Я очень удивлен, что никто не поднял этот вопрос, так как это самый очевидный и самый простой ответ, который применим почти в каждом отдельном случае.

6
KthProg

Существует несколько способов реализации модулей в 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
6
Willem van der Veen

Вот обходной путь для браузеров (не Node.js), использующих импорт HTML.

Во-первых, все классы и скрипты JavaScript находятся не в файлах .js, а в файлах .js.html (.js .html просто для распознавания между HTML-страницами и полными сценариями/классами JavaScript) внутри тегов <script>, например:

MyClass.js.html:

<script>
   class MyClass {

      // Your code here..

   }

</script>

Тогда, если вы хотите импортировать свой класс, вам просто нужно использовать импорт HTML:

<link rel="import" href="relative/path/to/MyClass.js.html"/>

<script>
   var myClass = new MyClass();
   // Your code here..
</script>

Правка: импорт HTML будет прекращен

Импорт HTML и модули ES6 уже хорошо реализованы в большинстве браузеров по всему миру . Но поскольку импорт HTML определенно не будет частью стандартов, в отличие от модулей ES6, его разработка будет прекращена, поэтому вам следует определенно начать использовать модули ES6.

6
Yairopro

Вот плагин Grunt , позволяющий вам использовать синтаксис @import "path/to/file.js"; в любом файле, включая файлы JavaScript. Это может быть в паре с Uglify или часы или любой другой плагин.

Его можно установить с помощью npm install: https://npmjs.org/package/grunt-import

6
Marcin

Лучше использовать jQuery путь. Чтобы отложить событие готовности, сначала вызовите функцию $.holdReady(true). Пример ( source ):

$.holdReady(true);
$.getScript("myplugin.js", function() {
    $.holdReady(false);
});
6
weageoo

Делайте это красиво, коротко, просто и легко! :]

// 3rd party plugins / script (don't forget the full path is necessary)
var FULL_PATH = '', s =
[
    FULL_PATH + 'plugins/script.js'      // Script example
    FULL_PATH + 'plugins/jquery.1.2.js', // jQuery Library 
    FULL_PATH + 'plugins/crypto-js/hmac-sha1.js',      // CryptoJS
    FULL_PATH + 'plugins/crypto-js/enc-base64-min.js'  // CryptoJS
];

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

 // initialize a single load 
load('plugins/script.js');

// initialize a full load of scripts
if (s.length > 0)
{
    for (i = 0; i < s.length; i++)
    {
        load(s[i]);
    }
}

Этот код является просто кратким функциональным примером, который может требует дополнительных функциональных возможностей для полной поддержки на любой (или данной) платформе.

5
tfont

Я делаю это следующим образом, создавая новый элемент и прикрепляя его к заголовку:

var x = document.createElement('script');
x.src = 'http://example.com/test.js';
document.getElementsByTagName("head")[0].appendChild(x);

В JQuery :

// jQuery
$.getScript('/path/to/imported/script.js', function()
{
    // Script is now loaded and executed.
    // Put your dependent JavaScript code here.
});
5
Rahul Srivastava

Только для NodeJS, это сработало для меня лучше всего!

Я пробовал большинство решений здесь, но ни одно из них не помогло мне просто загрузить другой файл без изменения области действия. Наконец-то я это использовал. Который сохраняет сферу и все. Это так же хорошо, как ваш код в этой точке.

const fs = require('fs');
eval(fs.readFileSync('file.js')+'');
5
rturkek

Это очень просто. Предположим, вы хотите импортировать файл A.js в файл B.js.

Теперь вы уверены, что вы связали B.js в HTML-файле, а затем просто свяжите A.js перед B.js в этом HTML-файле. Тогда открытые переменные A.js будут доступны внутри B.js

Это не требует сложного ответа.

4
Akshay Vijay Jain

У меня есть требование асинхронно загружать массив файлов JavaScript и в конце сделать обратный вызов. В основном мой лучший подход заключается в следующем:

// Load a JavaScript file from other JavaScript file
function loadScript(urlPack, callback) {
    var url = urlPack.shift();
    var subCallback;

    if (urlPack.length == 0) subCallback = callback;
    else subCallback = function () {
        console.log("Log script: " + new Date().getTime());
        loadScript(urlPack, callback);
    }

    // Adding the script tag to the head as suggested before
    var head = document.getElementsByTagName('head')[0];
    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 = subCallback;
    script.onload = subCallback;

    // Fire the loading
    head.appendChild(script);
}

Пример:

loadScript(
[
    "js/DataTable/jquery.dataTables.js",
    "js/DataTable/dataTables.bootstrap.js",
    "js/DataTable/dataTables.buttons.min.js",
    "js/DataTable/dataTables.colReorder.min.js",
    "js/DataTable/dataTables.fixedHeader.min.js",
    "js/DataTable/buttons.bootstrap.min.js",
    "js/DataTable/buttons.colVis.min.js",
    "js/DataTable/buttons.html5.min.js"
], function() { gpLoad(params); });

Второй скрипт не загрузится, пока первый полностью не загрузится, и так ...

Результаты:

 Result

4
MiBol

Если вы используете Angular, то модуль плагина $ ocLazyLoad может помочь вам сделать это. 

Вот некоторые цитаты из его документации:

Загрузите один или несколько модулей и компонентов с несколькими файлами:

$ocLazyLoad.load(['testModule.js', 'testModuleCtrl.js', 'testModuleService.js']);

Загрузите один или несколько модулей с несколькими файлами и укажите необходимый тип: Примечание. При использовании форматирования в стиле requireJS (например, с js! В начале) не указывайте расширение файла. Используйте один или другой.

$ocLazyLoad.load([
  'testModule.js',
   {type: 'css', path: 'testModuleCtrl'},
   {type: 'html', path: 'testModuleCtrl.html'},
   {type: 'js', path: 'testModuleCtrl'},
   'js!testModuleService',
   'less!testModuleLessFile'
]);

Вы можете загрузить внешние библиотеки (не угловые):

$ocLazyLoad.load(['testModule.js', 
   'bower_components/bootstrap/dist/js/bootstrap.js', 'anotherModule.js']);

Вы также можете загрузить файлы CSS и шаблонов:

 $ocLazyLoad.load([
     'bower_components/bootstrap/dist/js/bootstrap.js',
     'bower_components/bootstrap/dist/css/bootstrap.css',
     'partials/template1.html'
 ]);
4
gm2008

Импорт и экспорт модулей с использованием ES6, которые работают с Node.js

Называйте файлы с расширением .mjs вместо .js

Создавать файлы

touch main.mjs lib.mjs

main.js

import { add } from './lib.mjs';
console.log(add(40, 2));

lib.mjs

export let add = (x,y) => {
  return x + y
}

Бежать

node --experimental-modules main.js
3
jasonleonhard

Теперь я могу быть совершенно заблуждающимся, но вот что я недавно начал делать ... Запустите и завершите ваши файлы JavaScript с помощью возврата каретки, поместите в скрипт PHP, а затем еще один возврат каретки . Комментарий JavaScript "//" игнорируется PHP, поэтому включение все равно происходит. Целью возврата каретки является то, что первая строка вашего включенного JavaScript не закомментирована.

Технически, вам не нужен комментарий, но он публикует ошибки в Dreamweaver , которые меня раздражают. Если вы пишете сценарий в IDE, который не публикует сообщения об ошибках, вам не нужны комментарии или возврат каретки.

\n
//<?php require_once("path/to/javascript/dependency.js"); ?>

function myFunction(){
    // stuff
}
\n
3
Duncan
var s=["Hscript.js","checkRobert.js","Hscript.js"];
for(i=0;i<s.length;i++){
  var script=document.createElement("script");
  script.type="text/javascript";
  script.src=s[i];
  document.getElementsByTagName("head")[0].appendChild(script)
};
3
Robert A

Не забудьте проверить LAB.js !

<script type="text/javascript">
       $LAB
       .script("jquery-1.8.3.js").wait()
       .script("scripts/clientscript.js");      
</script>
3
emolaus

В прошлом проекте я довольно успешно использовал ajile для импорта повторно используемых файлов JavaScript. Я всегда хотел, чтобы была функция для этого встроенная в сам JavaScript.

3
jpierson

Другой подход заключается в использовании импорта HTML. Они могут содержать ссылки на скрипты, а также ссылки на таблицы стилей.

Вы можете просто связать файл HTML, как

<link rel="import" href="vendorScripts.html"/>

В файле vendorScripts.html вы можете включить ссылки на свои скрипты, такие как:

<script src="scripts/vendors/jquery.js"></script>
<script src="scripts/vendors/bootstrap.js"></script>
<script src="scripts/vendors/angular.js"></script>
<script src="scripts/vendors/angular-route.js"></script>

Посмотрите на HTML Imports для более подробной информации.

К сожалению, это работает только в Chrome.

2
gabriel211

Вы не можете импортировать, но вы можете ссылаться.

PhpShtorm IDE. Для ссылки в одном файле .js на другой файл .js просто добавьте это в начало файла:

<reference path="../js/file.js" />

Конечно, вы должны использовать свой собственный путь к файлу JavaScript.

Я не знаю, будет ли это работать в других IDE. Наверное, да, просто попробуйте. Это должно работать и в Visual Studio.

2
Evgeniy Miroshnichenko

Да, есть ...

Продолжайте читать, в ES6, мы можем export и import часть или весь файл javascript в другой ...

Но подождите, ES6 поддерживается не во всех браузерах, так что вам нужно передать его, например, с помощью babel.js ...

Итак, вы создаете класс, как показано ниже:

class Person {
  constructor(name) {
    this.name = name;
  }

  build() {
    return new Person(this);
  }
}

module.exports = Person;

в другом файле JavaScript выполните импорт следующим образом:

import { Person } from 'Person';

Вы также можете потребовать файл как:

const Person = require('./Person');

Если вы используете более старую версию JavaScript, вы можете использовать requirejs:

requirejs(["helper/util"], function(util) {
    //This function is called when scripts/helper/util.js is loaded.
    //If util.js calls define(), then this function is not fired until
    //util's dependencies have loaded, and the util argument will hold
    //the module value for "helper/util".
});

Если вы хотите придерживаться более старых версий материалов, таких как jQuery, вы также можете использовать что-то вроде getScript:

jQuery.getScript('./another-script.js', function() {
    // Call back after another-script loaded
});

И последнее, но не менее важное: не забывайте, что вы можете сделать традиционный способ создания сценариев, используя тег <script> ...

<script src="./first-script.js"></script>
<script src="./second-script.js"></script>
<script src="./third-script.js"></script>

Есть также атрибуты async и defer, о которых я должен упомянуть здесь ...

Примечание: Существует несколько способов выполнения внешнего скрипта:

  • Если присутствует асинхронность: сценарий выполняется асинхронно с остальной частью страницы (сценарий будет выполняться, пока страница продолжает анализ)
  • Если async отсутствует и defer равен присутствует: скрипт выполняется после завершения страницы разбор
  • Если нет ни асинхронного, ни отсроченного: сценарий извлекается и выполняется немедленно, прежде чем браузер продолжит работу парсинг страницы
2
Alireza

Вот, может быть, другой путь! В Node.js вы делаете это, как показано ниже! http://requirejs.org/docs/node.html

sub.js

module.exports = {
  log: function(string) {
    if(console) console.log(string);
  }
  mylog: function(){
    console.log('just for log test!');
  }
}

main.js

var mylog =require('./sub');

mylog.log('Hurray, it works! :)');
mylog.mylog();
2
xgqfrms

Я пробовал эту проблему с другим подходом,

Порядок импорта скриптов здесь не имеет никакого значения.

index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Trials</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="main.js"></script>
    <script src="scriptA.js"></script>
</head>

<body>
<h3>testing js in js (check console logs)</h3>
<button onclick="fnClick()">TEST</button>
</body>

</html>

main.js

function fnClick() {
  console.log('From\tAAAAA');
  var pro = myExpo.hello();
  console.log(pro);
}

scriptA.js

myExpo = {
    hello: function () {
        console.log('From\tBBBBB');
        return "Hello";
    }
}

и результат есть

From    AAAAA
From    BBBBB
Hello
1
Milton Ain

Если вы обнаружите, что два или более сценария занимают одну и ту же функцию при вызове, мы не можем включить их в одно и то же время, нам нужно сделать это dynamic по выбору пользователя.

Включение других файлов в jQuery с использованием $.getScript работает, так как скрипт по умолчанию не кэшируется . Таким образом, мы сохраняем, чтобы вызвать другие сценарии. Звонки могут быть организованы так:

HTML

<select class="choice">
  <option value="script1" selected>Script-1</option>
  <option value="script2">Script-2</option>
</select>

JS 

  $(".choice").change(on_change);

    var url = "https://example.com";
    $.url1 = url + "/script1.js";
    $.url2 = url + "/script2.js";

  function on_change() {
    if ($(".choice").val()=="script1") {
        script1();
    } else {
        script2();
    }

    // script1
    function script1() {   
      $.getScript($.url1, function( data, textStatus, jqxhr ) {
          //excecute here
      });  
    }

    // script2
    function script2() {
       $.getScript($.url2, function( data, textStatus, jqxhr ) {
          //excecute here
      });  
    }
0
Chetabahana

Обратите внимание, что мы обычно используем статические скрипты. Поэтому мы хотим извлечь из cache как можно больше . Это экономит сетевой трафик и ускоряет посадку.

Использование

$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
  console.log( textStatus );
});

cache: true добавлена ​​опция в метод ajax

0
Adam111p
var xxx = require("../lib/your-library.js")

или же

import xxx from "../lib/your-library.js" //get default export
import {specificPart} from '../lib/your-library.js' //get named export
import * as _name from '../lib/your-library.js'  //get full export to alias _name
0
Mesut Yiğit

Вы можете использовать мой loadScript ES module для загрузки файлов javaScript.

Использование:

В теге head включите следующий код:

<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.js"></script>

или же

<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.min.js"></script>

Теперь вы можете использовать window.loadScript для загрузки ваших файлов JavaScript.

loadScript.async (src, [options])

Асинхронная загрузка файла JavaScript.

src: URL-адрес внешнего файла сценария или массив имен файлов сценария.

опции: доступны следующие опции

onload: function () The onload event occurs when a script has been loaded. Default is undefined.

onerror: function ( str, e ) The onerror event occurs when an error has been occured. Default is undefined.

    str: error details

    e: event

appendTo: The node to which the new script will be append. Default is head node.

Например

loadScript.async( "JavaScript.js",
        {
            onload: function () {

                var str = 'file has been loaded successfully';
                console.log( str );

            },
            onerror: function ( str, e ) {

                console.error( str );

            },

        } );

Пример использования

0
Andrej

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

Вышеприведенная функция прекрасно работает, если вы загружаете только один скрипт или вам не нужен порядок загрузки нескольких скриптов. Если у вас есть некоторые сценарии, которые зависят от других, вам нужно использовать Promise , чтобы указать порядок загрузки. Причиной этого является то, что Javascript асинхронно загружает такие ресурсы, как сценарии и изображения. Последовательность загрузки не зависит от последовательности асинхронных вызовов, а это значит, что script1 не будет загружаться до script2, даже если вы вызовете dynamicallyLoadScript("scrip1") перед вызовом dynamicallyLoadScript("scrip2")

Итак, вот еще одна версия dynamicicallyLoadScript, который гарантирует порядок загрузки:

// Based on: https://javascript.info/promise-basics#example-loadscript
function dynamicallyLoadScript(url) {
        return new Promise(function(resolve, reject) {
        var script = document.createElement("script");
        script.src = url;
        script.onload = resolve;
        script.onerror = () => reject(new Error(`Error when loading ${url}!`));
        document.body.appendChild(script);
    });

Подробнее об обещаниях см. эта отличная страница .

Использование этого нового dynamicicallyLoadScript очень просто:

dynamicallyLoadScript("script1.js")
.then(() => dynamicallyLoadScript("script2.js"))
.then(() => dynamicallyLoadScript("script3.js"))
.then(() => dynamicallyLoadScript("script4.js"))
.then(() => dynamicallyLoadScript("script5.js"))
//...

Теперь скрипты загружаются в следующем порядке: script1.js, script2.js, script3.js и т.д.

Запуск зависимого кода после загрузки скрипта

Кроме того, вы можете сразу запустить код, который использует скрипты после их загрузки. Просто добавьте другой .then после загрузки скрипта:

dynamicallyLoadScript("script1.js")
.then(() => dynamicallyLoadScript("script2.js"))
.then(() => foo()) // foo can be a function defined in either script1, script2
.then(() => dynamicallyLoadScript("script3.js"))
.then(() => {
     if (var1){ // var1 can be a global variable defined in either script1, script2, or script3
          bar(var1); // bar can be a function defined in either script1, script2, or script3
     } else {
          foo(var1);
     }
})
//more .then chains...

Обрабатывать ошибки загрузки

Чтобы отобразить необработанные отклонения обещаний (ошибки при загрузке скриптов и т.д.), Поместите прослушиватель событий unhandledrejection вверху кода:

// Based on: https://javascript.info/promise-error-handling#unhandled-rejections
window.addEventListener('unhandledrejection', function(event) {
     // the event object has two special properties:
     console.error(event.promise);// the promise that generated the error
     console.error(event.reason); // the unhandled error object
});

Теперь вы будете уведомлены о любых ошибках загрузки скрипта.


Функция быстрого доступа

Если вы загружаете много скриптов без выполнения кода сразу после загрузки, эта сокращенная функция может пригодиться:

function dynamicallyLoadScripts(urls){
        if (urls.length === 0){
            return;
        }
        let promise = dynamicallyLoadScript(urls[0]);
        urls.slice(1).forEach(url => {
            promise = promise.then(() => dynamicallyLoadScript(url));
        });
    }

Чтобы использовать его, просто передайте массив URL-адресов скриптов, например:

const scriptURLs = ["dist/script1.js", "dist/script2.js", "dist/script3.js"];
dynamicallyLoadScripts(scriptURLs);

Скрипты будут загружены в порядке их появления в массиве.

0
AlienKevin