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

avatar
Alec Smart
4 июня 2009 в 11:59
3638341
68
5715

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

Источник

Ответы (68)

avatar
e-satis
4 июня 2009 в 12:13
4938

В старых версиях 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 [«CJS»] в Node.js), вы либо используйте "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. Проверьте текущую поддержку на caniuse. Нет необходимости использовать расширение Node.js .mjs; браузеры полностью игнорируют расширения файлов в модулях / скриптах.

<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: загрузка динамического скрипта.

Обнаружение, когда сценарий был выполнен

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

Alien
15 августа 2020 в 17:33
0

Я загрузил div динамически, щелкнув меню без загрузки страницы, используя хеш URL. Моя проблема в том, что когда я нажимаю одну и ту же страницу 2/3 раза, js загружается 2/3 раза. вот почему каждое событие происходит многократно. Я хочу проверить файл js, уже загруженный в нижний колонтитул / заголовок, перед добавлением в этот код: var js = document.createElement ("script"); js.type = "текст / javascript"; js.src = jsFilePath; document.body.appendChild (js);

Glund
5 января 2021 в 15:22
0

Спасибо за ваш вклад. Есть ли вообще способ вставить скрипт в начало головы?

Steven Ventimiglia
22 февраля 2021 в 01:48
0

Вы также можете использовать что-то вроде Gulp (gulpjs.com) для их предварительной обработки с выходом в виде одного вызываемого файла. Например: а) объедините несколько файлов JavaScript в один, б) используйте Babel для обеспечения обратной совместимости, в) minify / uglify для удаления комментариев, пробелов и т. Д. Затем вы не только организовали эти файлы, но и оптимизировали их. а также путем запуска конвейера с возможностью сделать то же самое для других форматов файлов (таких как CSS и изображения).

David Spector
27 мая 2021 в 15:47
0

jakearchibald.com/2017/es-modules-in-browsers кажется мертвой ссылкой.

avatar
Mount Mario
26 февраля 2022 в 18:46
1

Вы можете просто использовать функцию require(); тег.

Например, если бы у меня был модуль add.js, который я хотел бы добавить в math.js, я бы сделал следующее:

//this is math.js

//vars
let a = 1;
let b = 3;

//start of code
const additionfile = require('addition.js');
window.alert("You added " + a + " and " + b + " together, to get " + additionfile.add(a,b) + "!");

если вам нужен файл add.js, он будет выглядеть примерно так

function add(a,b) {
   const sum = a + b;
   return sum;
}
avatar
Enripro
6 января 2022 в 12:37
0

Это так просто:

var js = document.createElement("script");

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

document.body.appendChild(js);
avatar
Enripro
6 января 2022 в 10:20
0

Итак, если вы хотите быстро и легко... Попробуйте это:

function include(filename)
{
    var head = document.getElementsByTagName('head')[0];

    var script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';

    head.appendChild(script)
}
avatar
Nirvana
19 октября 2021 в 06:36
0

На сервере вы можете использовать модули CommonJS. Например:

//a.js
function func () {}

module.exports = { func };
//b.js
var a = require('./a.js');
console.log(a.func);
avatar
smallscript
5 июля 2021 в 01:10
1

Мое общее решение взято из библиотеки efekt.js.st из EdgeS (автор которого я) .

бесстыдное предупреждение о подключении - я нахожусь на других сайтах сети stackexchange. Это повторная ссылка на https://codereview.stackexchange.com/questions/263764/dynamic-load-css-or-script.

Какой код или дизайн вы бы использовали для поддержки динамической загрузки css и scripts?

Требования

  • поддержка обещание-ожидание-async , включая обработку ошибок
  • поддержка однократная загрузка кэширование, включая перезагрузку
  • поддерживает нагрузку в head, body или текущую script-element
  • поддержка нагрузки css, js, mjs модули или другие типы скриптов
  • поддерживает другой тег attrs , например nonce, crossorigin и т. Д.
static loadScriptOrStyle(url, options) {
  // provenance :<# **Smallscript EdgeS efekt** `efekt.js.st` github libraries #>
  // returns    :<Promise#onload;onerror>
  // options    :<# `fIgnoreCache`, `fAppendToHead`, `fUrlIsStyle`, `attrs:{}` #>
  const head = document.head; let node = options?.fAppendToBody ? document.body : head;
  const url_loader_cache = document.head.url_loader_cache
    ? head.url_loader_cache
    : (head.url_loader_cache = {script:{},link:{}})
  const kind = (options?.fUrlIsStyle || /\.css(?:(?:\?|#).*)?$/i.test(url))
    ? 'link' : 'script';
  // check already-loaded cache
  if(url_loader_cache[kind][url]) {
    const el = url_loader_cache[kind][url];
    // support `fIgnoreCache` reload-option; should not use on `head`
    if(options?.fIgnoreCache)
      el.remove();
    else
      return(new CustomEvent('cache',{detail:el}));
  }
  // (re)create and record it
  const self = document.currentScript;
  const el = url_loader_cache[kind][url] = document.createElement(kind);
  const append = (!self || options?.fAppendToHead || options?.fAppendToBody)
    ? el => node.appendChild(el)
    : el => self.parentNode.insertBefore(el, self);
  const load = new Promise((resolve, reject) => {
    el.onload  = e => {e.detail = el;resolve(e)};
    el.onerror = e => {e.detail = el;reject(e)};
    // `onload` or `onerror` possibly alter `cache` value
    // throw(new URIError(`The ${url} didn't load correctly.`))
  });
  // configure `module` attr, as appropriate
  if(/\.mjs(?:(?:\?|#).*)?$/i.test(url))
    el.type = 'module'
  // configure other attrs as appropriate (referrer, nonce, etc)
  for(const key in options?.attrs) {el[key] = attrs[key]}
  // trigger it
  if(kind === 'link') el.rel = 'stylesheet', el.href = url; else el.src = url;
  append(el);
  return(load);
}
avatar
Anonymous
10 июня 2021 в 23:29
2

Сделайте fetch запрос и eval результат.

avatar
Biplov Kumar
9 октября 2020 в 05:34
3
Step 1: Declare the function in another class.

    export const myreport = (value) => {
    color = value.color;
    name = value.name;
    
    var mytext = name + " | " + color;
    return mytext;
    }

Step 2:- Import that function which is needed to be used.

    import {myreport} from '../../Test'

Step 3:- Use that function.

let val = { color: "red", name: "error" }
var resultText = myreport(val)
console.log("resultText :- ", resultText)
avatar
Dangerousgame
19 мая 2020 в 09:01
-4

Вы должны использовать это:

<script src="your_file.js"></script>

Легко!

avatar
user
20 апреля 2020 в 19:15
0

Вы также можете использовать gulp, gulp-concat, gulp-typescript с /// <reference path= включает:

packages.json

{
  "scripts": {
    "gulp": "gulp main"
  },
  "dependencies": {
    "@types/gulp": "^4.0.6",
    "@types/gulp-concat",
    "@types/gulp-typescript",
    "gulp": "^4.0.2",
    "gulp-concat": "^2.6.1",
    "gulp-resolve-dependencies": "^3.0.1",
    "gulp-typescript": "^6.0.0-alpha.1",
    "typescript": "^3.7.3"
  }
}

src/someimport.ts

class SomeClass {
    delay: number;
}

src/main.ts

/// <reference path="./someimport.ts" />

someclass = new SomeClass();
someclass.delay = 1;

Эта main задача gulp (на gulpfile.js) нацелена только на файл src/main.js, разрешая все его ссылки /// <reference path=... include. Эти включения известны как Triple-Slash Directives и используются только инструментами транспилятора для объединения файлов. В нашем случае они явно используются .pipe(resolveDependencies({ и самим машинописным текстом при проверке файла на отсутствие типов, переменных и т. Д.

  1. https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html
  2. Когда мне нужна ссылка на тройную косую черту?

Обратитесь к https://github.com/ivogabe/gulp-typescript#api-overview, если вы хотите настроить вызов var tsProject = ts.createProject и не использовать файл tsconfig.json или переопределить его параметры.

gulpfile.js

var gulp = require("gulp");
var concat = require('gulp-concat');
var resolveDependencies = require('gulp-resolve-dependencies');

var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");

gulp.task("main", function() {
  return gulp
    .src(["src/main.ts"])
    .pipe(resolveDependencies({
      pattern: /^\s*\/\/\/\s*<\s*reference\s*path\s*=\s*(?:"|')([^'"\n]+)/gm
    }))
    .on('error', function(err) {
        console.log(err.message);
    })
    .pipe(tsProject())
    .pipe(concat('main.js'))
    .pipe(gulp.dest("build/"));
});

Если вы хотите настроить таргетинг на все файлы проекта сценария вашего типа, а не только на src/main.ts, вы можете заменить это:

  return gulp
    .src(["src/main.ts"])
    .pipe(resolveDependencies({
    ...
// -->
  return tsProject
    .src()
    .pipe(resolveDependencies({
    ...

Если вы не хотите использовать typescript, вы можете использовать этот упрощенный gulpfile.js и удалить все typescript из package.json:

gulpfile.js

var gulp = require("gulp");
var concat = require('gulp-concat');
var resolveDependencies = require('gulp-resolve-dependencies');

gulp.task("main", function() {
  return gulp
    .src(["src/main.js"])
    .pipe(resolveDependencies({
      pattern: /^\s*\/\/\/\s*<\s*reference\s*path\s*=\s*(?:"|')([^'"\n]+)/gm
    }))
    .on('error', function(err) {
        console.log(err.message);
    })
    .pipe(concat('main.js'))
    .pipe(gulp.dest("build/"));
});

packages.json

{
  "scripts": {
    "gulp": "gulp main"
  },
  "dependencies": {
    "gulp": "^4.0.2",
    "gulp-concat": "^2.6.1",
    "gulp-resolve-dependencies": "^3.0.1"
  }
}

Затем, после выполнения команды npm run gulp, создается файл build/main.js со следующим содержимым:

build/main.js

class SomeClass {
}
/// <reference path="./someimport.ts" />
someclass = new SomeClass();
someclass.delay = 1;

Что позволяет мне включить его в браузер с тегом script после обслуживания файлов каталога build:

<html>
    <head>
        <script src="main.js"></script>
    </head>
    <body>
        <script type="text/javascript">
            console.log(someclass.delay);
        </script>
    </body>
</html>

Связанные вопросы:

  1. https://www.typescriptlang.org/docs/handbook/gulp.html
  2. Могу ли я использовать машинописный текст без requireJS?
  3. Gulp простое объединение основного файла, для которого требуется другой файл JS
  4. Клиент на узле: неперехваченная ошибка ReferenceError: требование не определено
  5. Как можно скомпилировать модули узла браузера машинописного текста с помощью gulp?
  6. Объедините файлы с помощью babel
  7. Как требовать модули CommonJS в браузере?
  8. Есть ли альтернатива Browserify?
avatar
Hmerman6006
17 апреля 2020 в 18:20
0

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

Например, у вас есть файлы с именами 'jsMod.js', 'jsView' и 'jsContr.js':


    //jsMod.js file
    JSMODOBJ = {};
    JSMODOBJ.valueAddition = function(/* element value 1 */ val1,
                                          /* element value 2 */ val2) {
        return val1 + val2;
    }


    //jsView.js file
    JSVIEWOBJ = {};
    JSVIEWOBJ.elementColour = function(/* element id to change colour */ id,
                                          /* css colour classname */ col) {
        document.getElementById(id).className = col;
    }


    //jsContr.js file
    JSCONTROBJ = {};
    var jsMod = JSMODOBJ;
    var jsView = JSVIEWOBJ;

    JSCONTROBJ.changeColourByValue = function (val1, val2, id, clss) {
        if (jsMod.valueAddition(val1,val2) !== 0) {
            jsView.elementColour(id, clss);
        }
    }

Затем вы можете установить файлы .js динамически, вставив scripts в свой файл .html или .php:

<?php
    echo "<script src = './js/dleafView.js'></script>
        <script src = './js/dleafModule.js'></script>
        <script src = './js/dleafContr.js'></script>";
?>

Затем просто вызовите функцию управления в теге <script type="text/javascript"></script>. Конечно, вначале это займет много времени, но в конечном итоге это сэкономит ваше время.

Я использую это немного по-другому, но этот способ тоже работает.

avatar
Torxed
9 октября 2019 в 19:29
1

Итак, это крайний случай. Но если вам нужно загрузить JavaScript из удаленного источника, большинство современных браузеров могут блокировать ваши межсайтовые запросы из-за CORS или чего-то подобного. Так нормально

<script src="https://another-domain.com/example.js"></script>

Не сработает. И выполнение document.createElement('script').src = '...' тоже не поможет. Вместо этого вы могли бы загрузить java-скрипт как ресурс через стандартный запрос GET и сделать следующее:

<script type="text/javascript">
    var script = document.createElement('script');
    script.type = 'text/javascript';

    let xhr = new XMLHttpRequest();
    xhr.open("GET", 'https://raw.githubusercontent.com/Torxed/slimWebSocket/master/slimWebSocket.js', true);
    xhr.onreadystatechange = function() {
        if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
            script.innerHTML = this.responseText; // <-- This one
            document.head.appendChild(script);
        }
    }
    xhr.send();
</script>

Захватив содержимое самостоятельно, браузер не заметит злонамеренных действий и позволит вам выполнить запрос. Затем вы добавляете его вместо <script> в innerHTML. Это по-прежнему заставляет браузер (по крайней мере, протестирован в Chrome) анализировать / выполнять скрипт.

Опять же, это крайний вариант использования. И, вероятно, у вас не будет обратной совместимости или совместимости с браузером. Но забавная / полезная вещь, о которой нужно знать.

avatar
Kamil Kiełczewski
10 июля 2019 в 16:12
13

Модули ES6

Да , используйте type = "module" в теге скрипта (поддержка):

<script type="module" src="script.js"></script>

И в файл script.js включите другой файл, подобный этому:

import { hello } from './module.js';
...
// alert(hello());

В 'module.js' вы должны экспортировать функцию / класс, который вы будете импортировать:

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

Рабочий пример находится здесь.

avatar
Kamil Dąbrowski
3 июля 2019 в 15:43
2

Небольшое расширение библиотеки из , ответ Дэна Даскалеску взят из идеи Facebook.

(function() {
var __ = {};
this._ = function(name, callback) {
    if(__[name]==undefined) {
        __[name] = true;
        var firstScript = document.getElementsByTagName('script')[0],
          js = document.createElement('script');
          js.src =  name;
          js.onload = callback;
          firstScript.parentNode.insertBefore(js, firstScript);
    }
}
})();

(new _('https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js', function() {
 snowStorm.snowColor = '#99ccff';
}));
avatar
Andrej
1 июня 2019 в 03:21
1

Вы можете использовать мой модуль loadScript ES для загрузки файлов 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, [параметры])

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

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

options: доступны следующие варианты

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 occurred. The default is undefined.

    str: error details

    e: event

appendTo: The node to which the new script will be append. The default is the 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 );
            },
        } );

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

avatar
AlienKevin
4 марта 2019 в 15:47
3

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

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

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

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

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

Использовать этот новый dynamicLoadScript очень просто:

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

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

PhysicalEd
28 октября 2020 в 00:17
0

Это прекрасное решение, и оно очень хорошо объяснено. Браво и спасибо.

avatar
MishkuMoss
17 января 2019 в 10:46
5

Я попытался решить эту проблему с другим подходом,

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

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
avatar
Willem van der Veen
10 августа 2018 в 17:11
11

Есть несколько способов реализовать модули в 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 (используется в Node.js)

Эта система модуляции используется в Node.js. Вы в основном добавляете свой экспорт в объект, который называется 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
avatar
jasonleonhard
24 июля 2018 в 01:45
6

Импорт и экспорт модулей с использованием 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
avatar
chickens
23 июня 2018 в 06:15
9

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

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

const fs = require('fs');
eval(fs.readFileSync('file.js') + '');
Peter Mortensen
3 октября 2020 в 20:20
0

Почему последний срок? Кажется, это ничего не делает.

chickens
4 октября 2020 в 12:20
0

readFileSync возвращает буфер. + '' преобразует это в строку.

avatar
Alireza
22 мая 2018 в 12:41
10

Да, есть ...

Продолжайте читать. В 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 не присутствуют: сценарий извлекается и выполняется немедленно, прежде чем браузер продолжит работу разбор страницы
avatar
Chetabahana
15 мая 2018 в 11:57
2

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

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

HTML

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

JavaScript

  $(".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 ) {
          // Execute here
      });
    }

    // script2
    function script2() {
       $.getScript($.url2, function( data, textStatus, jqxhr ) {
          // Execute here
      });
    }
avatar
Adam111p
23 апреля 2018 в 19:35
2

Обратите внимание, что мы обычно используем статические скрипты . Итак, мы хотим быть взяты из кеша как можно больше.

Это экономит сетевой трафик и ускоряет посадку.

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

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

Параметр cache: true был добавлен в метод Ajax.

avatar
KthProg
12 апреля 2018 в 19:38
15

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

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

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

Nathan Kovner
27 июля 2020 в 18:44
0

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

Peter Mortensen
3 октября 2020 в 20:31
0

Но это работает только в веб-браузере? А как насчет автономного модульного тестирования (скажем, под Node.js)?

avatar
Dmitry Sheiko
20 июля 2017 в 15:15
18

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

function loadJs( url ){
  return new Promise(( resolve, reject ) => {
    if (document.querySelector( `head > script[ src = "${url}" ]`) !== null ){
        console.warn( `script already loaded: ${url}` );
        resolve();
    }
    const script = document.createElement( "script" );
    script.src = url;
    script.onload = resolve;
    script.onerror = function( reason ){
        // This can be useful for your error-handling code
        reason.message = `error trying to load script ${url}`;
        reject( reason );
    };
    document.head.appendChild( script );
  });
}

Использование (async / await):

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 => {} );
mike rodent
19 июля 2020 в 07:25
0

Это очень хорошо, если вы не хотите связываться с модулями и не хотите использовать функцию обратного вызова, но хотите использовать async / await.

Flimm
12 мая 2021 в 13:00
0

url необходимо правильно экранировать здесь: `head > script[ src = "${url}" ]`

avatar
Akshay Vijay Jain
15 мая 2017 в 05:00
5

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

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

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

avatar
Yairopro
4 мая 2017 в 15:16
9

Вот обходной путь для браузеров (не 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. Следует использовать модули ES6.

avatar
gm2008
13 апреля 2017 в 10:42
6

Если вы используете 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'
]);

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

$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'
 ]);
avatar
gabriel211
16 ноября 2016 в 22:36
3

Другой подход - использовать импорт 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.

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

PhysicalEd
27 октября 2020 в 23:41
0

К сожалению, в ссылке HTML Imports указано, что эта функция устарела и удалена из Chrome - chromestatus.com/feature/5144752345317376

avatar
Mesut Yiğit
19 октября 2016 в 08:18
1
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
avatar
xgqfrms
4 октября 2016 в 13:47
6

Вот, может быть, другой способ!

В Node.js это можно сделать так же, как показано в следующем коде!

sub.js

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

main.js

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

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

ссылки

http://requirejs.org/docs/node.html

avatar
Evgeniy Miroshnichenko
12 августа 2016 в 11:18
3

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

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

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

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

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

avatar
MiBol
7 августа 2016 в 19:14
6

У меня есть требование асинхронно загрузить массив файлов 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

avatar
Rahul Srivastava
25 мая 2016 в 00:06
8

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

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.
});
avatar
Adem İlhan
24 июля 2015 в 06:53
27

Если вы намерены загрузить файл 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>
YektaDev
12 апреля 2021 в 08:00
0

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

avatar
Manohar Reddy Poreddy
22 июля 2015 в 02:15
21

У меня была простая проблема, но ответы на этот вопрос меня сбили с толку.

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

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

avatar
Dan Dascalescu
8 июля 2015 в 02:41
50

Вот обобщенная версия того, как 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/.

avatar
draupnie
17 апреля 2015 в 01:56
82

Заявление 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;
avatar
tfont
8 февраля 2015 в 01:19
12

Сделайте его красивым, коротким, простым и удобным в обслуживании! :]

// Third-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]);
    }
}

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

Peter Mortensen
3 октября 2020 в 20:53
0

Объяснение было бы в порядке. Например. в чем идея (принцип работы) и как работает?

avatar
curlyhairedgenius
11 января 2015 в 20:19
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 для проверки массива отложенных объектов, но теперь вы делаете это в каждом файле, и file2 будет считаться загруженным, как только $.when будет выполнен, а не при выполнении обратного вызова, поэтому файл1 все еще продолжает выполнение до загрузки файла3. У этого действительно все та же проблема.

Я решил пойти назад, а не вперед. Спасибо, 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;
    }
});

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

Файл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"
});
avatar
Turnerj
1 января 2015 в 08:58
17

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

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

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

avatar
Isaac Gregson
14 марта 2014 в 04:40
18

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

Из документации Mixture по .mix файлам:

Файлы микса - это просто файлы .js или .css с расширением .mix. в имени файла. А файл 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, за исключением того, что использую его как интерфейсный инструмент для разработки. Я столкнулся с этим вопросом, когда увидел файл JavaScript .mix в действии (в одном из шаблонов Mixture) и был немного сбит с толку («вы можете это сделать?» - подумал я про себя). Потом я понял, что это тип файла для конкретного приложения (несколько разочаровал, согласился). Тем не менее, полагал, что эти знания могут быть полезны другим.

Примечание: Выпуск смеси был прекращен 26.07.2016 (после того, как был открыт исходный код 12.04.2015).

Peter Mortensen
3 октября 2020 в 20:50
0

Лучше избегать «Обновления» (метаинформации, относящейся к истории изменений этого сообщения). Вместо этого примените его к контенту (не к этому сообщению), например «Смесь была открыта 12 апреля 2015 года, а выпуск этой смеси был прекращен 26 июля 2016 года».

avatar
heinob
11 декабря 2013 в 11:54
58

Вот синхронная версия без 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 в своем ответе.

avatar
Ale
22 ноября 2013 в 18:40
10

Также существует Head.js. Разобраться очень просто:

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

Как видите, это проще, чем Require.js, и так же удобно, как метод jQuery $.getScript. Он также имеет некоторые расширенные функции, такие как условная загрузка, обнаружение функций и и многое другое.

avatar
Venu immadi
13 ноября 2013 в 09:18
49

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

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

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

$.getScript("another_script.js");
avatar
Marcin
6 ноября 2013 в 17:35
7

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

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

avatar
Vicky Gonsalves
26 октября 2013 в 03:42
12

Этот сценарий добавит файл 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);
})();
avatar
Dmitry Sheiko
13 июля 2013 в 21:44
30

Большинство решений, показанных здесь, подразумевают динамическую загрузку. Вместо этого я искал компилятор, который собирает все зависимые файлы в один выходной файл. То же, что и препроцессоры Less / Sass, работают с at-правилом 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(){}
    }
};
avatar
Christopher Dumas
31 мая 2013 в 19:31
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-адреса. Он устанавливает его в асинхронный режим, поэтому он не блокирует остальную часть кода, но вызывает обратный вызов, когда состояние готовности (состояние загружаемого содержимого) изменяется на «загружено».

avatar
stamat
12 апреля 2013 в 16:34
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);
};
avatar
tggagne
24 марта 2013 в 19:32
24

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

xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);
avatar
Robert A
10 марта 2013 в 13:55
6
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)
};
avatar
Duncan
7 марта 2013 в 15:50
6

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

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

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

function myFunction(){
    // stuff
}
\n
avatar
emolaus
16 января 2013 в 14:04
6

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

<script type="text/javascript">
       $LAB
       .script("jquery-1.8.3.js").wait()
       .script("scripts/clientscript.js");      
</script>
avatar
weageoo
25 августа 2012 в 20:17
8

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

$.holdReady(true);
$.getScript("myplugin.js", function() {
    $.holdReady(false);
});
avatar
Sam4Code
22 августа 2012 в 04:33
15
var js = document.createElement("script");

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

document.body.appendChild(js);
avatar
Imdad
3 июля 2012 в 13:32
110

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

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

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

См .:

David Spector
27 мая 2021 в 15:52
0

Семь лет спустя этот ответ не работает: «SyntaxError: объявления импорта могут появляться только на верхнем уровне модуля».

Imdad
31 мая 2021 в 12:06
0

Поделитесь своим кодом, что вы пытаетесь сделать.

David Spector
31 мая 2021 в 17:04
0

Хорошо, вот код, который отлично работает: function Include (jsFilePath) {var js = d.createElement ("script"); js.type = "текст / javascript"; js.src = jsFilePath; d.body.appendChild (js); } // Включают

avatar
John Strickler
7 июня 2012 в 20:55
601

Если кто-то ищет что-то более продвинутое, попробуйте 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
});

implementation.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, а также более определенные модули. Он оптимизирован для использования в браузере, в том числе в Интернете. Worker, но его можно использовать в других средах JavaScript, например Rhino и Node. Он реализует API асинхронного модуля.

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

...

avatar
JMawer
7 июня 2012 в 20:48
24

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

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

См. Также:

avatar
jpierson
4 марта 2012 в 04:19
7

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

avatar
Wayne Molina
19 января 2012 в 21:27
10

Я создал функцию, которая позволит вам использовать словесность, аналогичную C # / Java, для включения файла JavaScript. Я немного протестировал его даже изнутри другого файла 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);
}
avatar
rgb_life
1 декабря 2011 в 05:36
11

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

  1. Создайте файл с именем «plugins.js» (или extension.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. Вам нужно написать его только один раз, и это столько же работы, сколько вызов плагина с помощью JavaScript.

Flimm
12 мая 2021 в 13:01
0

Обратите внимание: если pluginNames содержит специальные символы, это не сработает и может даже привести к уязвимости системы безопасности. Здесь вам нужно использовать правильное экранирование: $('head').append('<script src="js/plugins/' + this + '.js"></script>');

avatar
Ariel
8 сентября 2011 в 18:22
168

Другой способ, который, на мой взгляд, намного чище, - это сделать синхронный запрос 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(); 
avatar
Kipras
28 апреля 2011 в 15:25
220

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

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

$("head").append($("<script></script>").attr("src", url));

/* Note that following line of code is incorrect because it doesn't escape the
 * HTML attribute src correctly and will fail if `url` contains special characters:
 * $("head").append('<script src="' + url + '"></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></script').attr('src', 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-satis).

avatar
Calmarius
27 декабря 2010 в 21:03
35

Вы также можете собрать свои скрипты, используя 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
avatar
nornagon
23 января 2010 в 05:20
52

Я только что написал этот код 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>

Gist: http://gist.github.com/284442.

avatar
Arnaud Gouder de Beauregard
4 июня 2009 в 12:04
65

Может быть, вы сможете использовать эту функцию, которую я нашел на этой странице Как мне включить файл 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)
}
avatar
Svitlana Maksymchuk
4 июня 2009 в 12:02
111

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