Есть ли в JavaScript что-то похожее на @import
CSS, что позволяет включать файл JavaScript в другой файл JavaScript?
javascript
file
import
include
Алек Смарт
источник
источник
script
теги?Ответы:
В старых версиях JavaScript не было импорта, включения или требования, поэтому было разработано много разных подходов к этой проблеме.
Но с 2015 года (ES6) в JavaScript появился стандарт модулей ES6 для импорта модулей в Node.js, который также поддерживается большинством современных браузеров .
Для совместимости со старыми браузерами, создайте инструменты, такие как Webpack и Rollup, и / или инструменты транспиляции, такие как Babel. .
ES6 Модули
Модули ECMAScript (ES6) поддерживаются в Node.js начиная с версии 8.5 с
--experimental-modules
флагом и, по крайней мере, с версии Node.js версии 13.8.0 без флага. Чтобы включить "ESM" (по сравнению с предыдущей системой модулей CommonJS в стиле Node.js ["CJS"]), вы либо используете"type": "module"
вpackage.json
файле, либо задаете расширение файла.mjs
. (Аналогично, модули, написанные с помощью предыдущего модуля CJS Node.js, могут быть названы,.cjs
если по умолчанию используется ESM.)Использование
package.json
:Тогда
module.js
:Тогда
main.js
:Используя
.mjs
, вы получитеmodule.mjs
:Тогда
main.mjs
:Модули ECMAScript в браузерах
Браузеры поддерживают загрузку модулей ECMAScript напрямую (не требуются такие инструменты, как Webpack), начиная с Safari 10.1, Chrome 61, Firefox 60 и Edge 16. Проверьте текущую поддержку в caniuse . Нет необходимости использовать
.mjs
расширение Node.js ; браузеры полностью игнорируют расширения файлов в модулях / скриптах.Узнайте больше на https://jakearchibald.com/2017/es-modules-in-browsers/
Динамический импорт в браузерах
Динамический импорт позволяет скрипту загружать другие скрипты по мере необходимости:
Подробнее читайте на странице https://developers.google.com/web/updates/2017/11/dynamic-import.
Node.js требует
Более старый стиль модуля CJS, все еще широко используемый в Node.js, это
module.exports
/require
system.Существуют и другие способы включения JavaScript внешнего содержимого в браузерах, которые не требуют предварительной обработки.
AJAX Загрузка
Вы можете загрузить дополнительный скрипт с помощью вызова AJAX, а затем использовать его
eval
для запуска. Это самый простой способ, но он ограничен вашим доменом из-за модели безопасности песочницы JavaScript. Использованиеeval
также открывает дверь к ошибкам, взломам и проблемам безопасности.Загрузка Загрузка
Как и Dynamic Imports, вы можете загружать один или несколько сценариев с помощью
fetch
вызова, используя обещания для управления порядком выполнения зависимостей сценариев с помощью библиотеки Fetch Inject :Загрузка jQuery
Библиотека jQuery обеспечивает загрузку в одну строку :
Динамическая загрузка скриптов
Вы можете добавить тег HTML с URL скрипта в HTML. Чтобы избежать накладных расходов jQuery, это идеальное решение.
Скрипт может даже находиться на другом сервере. Кроме того, браузер оценивает код.
<script>
Тег может быть введен в любой веб - страницы<head>
, или вставить непосредственно перед закрывающим</body>
тегом.Вот пример того, как это может работать:
Эта функция добавит новый
<script>
тег в конец раздела заголовка страницы, где в качествеsrc
атрибута будет указан URL-адрес, который присвоен функции в качестве первого параметра.Оба эти решения обсуждаются и иллюстрируются в JavaScript Madness: динамическая загрузка скриптов .
Обнаружение, когда скрипт был выполнен
Теперь есть большая проблема, о которой вы должны знать. Это подразумевает, что вы загружаете код удаленно . Современные веб-браузеры загружают файл и продолжают выполнять ваш текущий скрипт, потому что они загружают все асинхронно для повышения производительности. (Это относится как к методу jQuery, так и к методу ручной динамической загрузки скрипта.)
Это означает, что если вы будете использовать эти приемы напрямую, вы не сможете использовать свой недавно загруженный код на следующей строке после того, как вы попросили его загрузить , потому что он все еще будет загружаться.
Например:
my_lovely_script.js
содержитMySuperObject
:Затем вы перезагрузите страницу, нажав F5. И это работает! Смешение ...
Так что с этим делать?
Ну, вы можете использовать взлом, который предлагает автор, по ссылке, которую я вам дал. Таким образом, для спешащих людей он использует событие для запуска функции обратного вызова при загрузке скрипта. Таким образом, вы можете поместить весь код с помощью удаленной библиотеки в функцию обратного вызова. Например:
Затем вы пишете код, который хотите использовать ПОСЛЕ того, как скрипт загружается в лямбда-функцию :
Затем вы запускаете все это:
Обратите внимание, что скрипт может выполняться после загрузки DOM или раньше, в зависимости от браузера и от того, включена ли строка
script.async = false;
. В общем , есть отличная статья о загрузке Javascript, которая обсуждает это.Слияние / предварительная обработка исходного кода
Как упоминалось в верхней части этого ответа, многие разработчики используют в своих проектах инструменты сборки / переноса, такие как Parcel, Webpack или Babel, что позволяет им использовать предстоящий синтаксис JavaScript, обеспечивать обратную совместимость для старых браузеров, объединять файлы, минимизировать, выполнять разбиение кода и т. д.
источник
onreadystatechange
событие иreadyState
свойство). Кроме того, динамическая загрузка сценариев не выигрывает у сканеров с предварительной загрузкой. Рекомендовать эту статью HTML5Rocks: html5rocks.com/en/tutorials/speed/script-loadingЕсли кто-то ищет что-то более продвинутое, попробуйте RequireJS . Вы получите дополнительные преимущества, такие как управление зависимостями, лучший параллелизм и избежание дублирования (то есть получение сценария более одного раза).
Вы можете написать свои файлы JavaScript в «модулях», а затем ссылаться на них как на зависимости в других скриптах. Или вы можете использовать RequireJS как простое решение «иди и получи этот скрипт».
Пример:
Определите зависимости как модули:
некоторые-dependency.js
creation.js - это ваш «основной» файл JavaScript, который зависит от some-dependency.js
Выдержка из GitHub README:
источник
На самом деле есть способ загрузить файл JavaScript не асинхронно, так что вы можете использовать функции, включенные в ваш недавно загруженный файл, сразу после загрузки, и я думаю, что он работает во всех браузерах.
Вы должны использовать
jQuery.append()
на<head>
элемент вашей страницы, то есть:Однако у этого метода также есть проблема: если в импортированном файле JavaScript возникает ошибка, Firebug (а также Firefox Error Console и Chrome Developer Tools также сообщат о своем месте неправильно, что является большой проблемой, если вы используете Firebug для отслеживания Ошибки JavaScript много (я делаю). Firebug по какой-то причине просто не знает о недавно загруженном файле, поэтому, если в этом файле происходит ошибка, он сообщает, что она произошла в вашем основном HTML- файле, и у вас будут проблемы с поиском истинной причины ошибки.
Но если это не проблема для вас, тогда этот метод должен работать.
На самом деле я написал плагин jQuery с именем $ .import_js (), который использует этот метод:
Поэтому все, что вам нужно сделать для импорта JavaScript, это:
Я также сделал простой тест для этого в Примере .
Он включает
main.js
файл в основной HTML, а затем скриптmain.js
использует$.import_js()
для импорта дополнительный файл с именемincluded.js
, который определяет эту функцию:И сразу же после включения
included.js
, тоhello()
функция вызывается, и вы получите уведомление.(Этот ответ является ответом на комментарий e-sat).
источник
jQuery.getScript
, чтобы вам не пришлось беспокоиться о написании плагина ...script
элемента вhead
заставит его работать асинхронно, если дляasync
него специально не установлено значениеfalse
."
, код сломаетсяДругой способ, который, на мой взгляд, намного чище, - это сделать синхронный Ajax-запрос вместо использования
<script>
тега. К тому же, как обрабатывает Node.js.Вот пример использования jQuery:
Затем вы можете использовать его в своем коде, как если бы вы обычно использовали include:
И сможете вызвать функцию из необходимого скрипта в следующей строке:
источник
async: false
предположительно устарел. Не то! Как говорится в вашей цитате, только материал, связанный с jqXHR.Есть хорошие новости для вас. Очень скоро вы сможете легко загрузить код JavaScript. Это станет стандартным способом импорта модулей кода JavaScript и станет частью самого ядра JavaScript.
Вам просто нужно написать,
import cond from 'cond.js';
чтобы загрузить макросcond
из файлаcond.js
.Таким образом, вам не нужно полагаться на какую-либо инфраструктуру JavaScript и не делать явных вызовов Ajax .
Ссылаться на:
Разрешение статического модуля
Модульные погрузчики
источник
Можно динамически генерировать тег JavaScript и добавлять его в документ HTML из другого кода JavaScript. Это загрузит целевой файл JavaScript.
источник
js.onload = callback;
Заявление
import
в ECMAScript 6.Синтаксис
источник
Может быть, вы можете использовать эту функцию, которую я нашел на этой странице Как мне включить файл JavaScript в файл JavaScript? :
источник
script.onload = callback;
var
, переменная будет глобальной?head
.Вот синхронная версия без jQuery :
Обратите внимание, что для получения этого рабочего междомена сервер должен будет установить
allow-origin
заголовок в своем ответе.источник
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)<script>
тег, а не черезXMLHttpRequest
.const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1");
Я только что написал этот код JavaScript (используя Prototype для манипулирования DOM ):
Применение:
Суть: http://gist.github.com/284442 .
источник
Вот обобщенная версия того, как Facebook делает это для их вездесущей кнопки «Нравится»:
Если это работает для Facebook, это будет работать для вас.
Причина, по которой мы ищем первый
script
элемент вместоhead
илиbody
заключается в том, что некоторые браузеры не создают его, если его не хватает, но у нас гарантированно будетscript
элемент - этот. Узнайте больше на http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ .источник
Если вы хотите в чистом JavaScript, вы можете использовать
document.write
.Если вы используете библиотеку jQuery, вы можете использовать
$.getScript
метод.источник
Вы также можете собрать свои скрипты, используя PHP :
Файл
main.js.php
:источник
Большинство представленных здесь решений предполагают динамическую загрузку. Вместо этого я искал компилятор, который собирает все зависимые файлы в один выходной файл. Так же, как препроцессоры 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
ЦСИ / Форма / вход / Tel.js
Теперь мы можем запустить компилятор:
И получите объединенный файл
сборки / main.js
источник
Если ваше намерение загрузить файл JavaScript использует функции из импортированного / включенного файла , вы также можете определить глобальный объект и установить функции в качестве элементов объекта. Например:
global.js
file1.js
file2.js
main.js
Вам просто нужно быть осторожным, когда вы включаете скрипты в файл HTML. Порядок должен быть таким, как показано ниже:
источник
Это должно сделать:
источник
eval
то , что случилось с ним. По словам Крокфорда , «eval
это зло. Этаeval
функция - наиболее часто используемая функция JavaScript. Избегайте ее.eval
Имеет псевдонимы. Не используйтеFunction
конструктор. Не передавайте строки вsetTimeout
илиsetInterval
». Если вы еще не читали его «JavaScript: Хорошие части», то выходите и делайте это прямо сейчас. Вы будете не пожалеете об этом.http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)Или вместо включения во время выполнения используйте сценарий для объединения перед загрузкой.
Я использую звездочки (я не знаю, есть ли другие). Вы строите свой код JavaScript в отдельных файлах и включаете комментарии, которые обрабатываются механизмом Sprockets, как и включенные. Для разработки вы можете включить файлы последовательно, а затем для производства, чтобы объединить их ...
Смотрите также:
источник
У меня была простая проблема, но я был озадачен ответами на этот вопрос.
Мне пришлось использовать переменную (myVar1), определенную в одном файле JavaScript (myvariables.js) в другом файле JavaScript (main.js).
Для этого я сделал, как показано ниже:
Загрузил код JavaScript в HTML-файле, в правильном порядке, сначала myvariables.js, затем main.js:
Файл: myvariables.js
Файл: main.js
Как вы видели, я использовал переменную в одном файле JavaScript в другом файле JavaScript, но мне не нужно было включать одну в другой. Мне просто нужно было убедиться, что первый файл JavaScript загружен до второго файла JavaScript, а переменные первого файла JavaScript доступны во втором файле JavaScript автоматически.
Это спасло мой день. Надеюсь, это поможет.
источник
import
. Вам нужен файл HTML, чтобы получить материал из одного файла JS в другой.<script>
тег. Это может помочь с организацией. Этот ответ просто не тот, о котором спрашивал вопрос, и не идеален в этом контексте.Если вы используете Web Workers и хотите включить дополнительные сценарии в область действия работника, другие ответы о добавлении сценариев в
head
тег и т. Д. Не будут работать для вас.К счастью, у Web Workers есть своя собственная
importScripts
функция, которая является глобальной функцией в области Web Worker, встроенной в сам браузер, поскольку является частью спецификации. .Кроме того, в качестве второго наиболее высоко оцененного ответа на ваш вопрос , RequireJS может также обрабатывать включение сценариев внутри Web Worker (вероятно, вызывающего
importScripts
себя, но с несколькими другими полезными функциями).источник
На современном языке с проверкой, если скрипт уже загружен, это будет:
Использование (async / await):
или
Использование (обещание):
источник
var pi = 3.14
. вызовите функцию loadJS () черезloadJs("pi.js").then(function(){ console.log(pi); });
@import
Синтаксис для достижения CSS-подобный JavaScript импортирования можно с помощью такого инструмента, как смеси через их особый.mix
тип файла (см здесь ). Я предполагаю, что приложение просто использует один из вышеупомянутых методов, хотя я не знаю.Из документации Mixture по
.mix
файлам:Вот пример
.mix
файла, который объединяет несколько.js
файлов в один:Mixture выводит это как,
scripts-global.js
а также как уменьшенную версию (scripts-global.min.js
).Примечание: я никоим образом не связан с Mixture, кроме того, что использую его в качестве внешнего инструмента разработки. Я столкнулся с этим вопросом, увидев
.mix
файл JavaScript в действии (в одном из шаблонов Mixture) и будучи немного смущенным этим («Вы можете сделать это?» - подумал я про себя). Затем я понял, что это был тип файла приложения (несколько разочаровывающий, согласился). Тем не менее, полагал, что знания могут быть полезны для других.ОБНОВЛЕНИЕ : Mixture теперь бесплатна (не в сети).
ОБНОВЛЕНИЕ : Смесь теперь прекращена. Старые релизы смеси все еще доступны
источник
источник
body
он еще не существует или не может быть изменен. Также это помогает объяснить ответы.Мой обычный метод:
Это прекрасно работает и не использует перезагрузки страницы для меня. Я попробовал метод AJAX (один из других ответов), но, похоже, он мне не подходит.
Вот объяснение того, как работает код для любопытных: по сути, он создает новый тег сценария (после первого) URL-адреса. Он устанавливает его в асинхронный режим, чтобы не блокировать остальную часть кода, а вызывает обратный вызов, когда readyState (состояние загружаемого содержимого) меняется на «загружен».
источник
Хотя эти ответы великолепны, существует простое «решение», существующее с момента загрузки скрипта, и оно охватит 99,999% случаев использования большинства людей. Просто включите сценарий, который вам нужен, прежде чем сценарий, который требует этого. Для большинства проектов не требуется много времени, чтобы определить, какие сценарии нужны и в каком порядке.
Если script2 требует script1, это действительно самый простой способ сделать что-то подобное. Я очень удивлен, что никто не поднял этот вопрос, так как это самый очевидный и самый простой ответ, который применим почти в каждом отдельном случае.
источник
Я написал простой модуль, который автоматизирует работу по импорту / включению скриптов модуля в JavaScript. Для подробного объяснения кода обратитесь к сообщению в блоге JavaScript require / import / include modules .
источник
Этот скрипт добавит файл JavaScript в начало любого другого
<script>
тега:источник
Существует также Head.js . Это очень легко иметь дело с:
Как видите, это проще, чем Require.js и так же удобно, как
$.getScript
метод jQuery . Он также имеет некоторые расширенные функции, такие как условная загрузка, обнаружение функций и многое другое .источник
Есть много потенциальных ответов на этот вопрос. Мой ответ, очевидно, основан на ряде из них. Это то, чем я закончил, прочитав все ответы.
Проблема с
$.getScript
любым другим решением, которое требует обратного вызова при завершении загрузки, заключается в том, что если у вас есть несколько файлов, которые используют его и зависят друг от друга, у вас больше не будет способа узнать, когда все сценарии были загружены (после того, как они вложены). в нескольких файлах).Пример:
file3.js
file2.js:
file1.js:
Вы правы, когда говорите, что можете указать синхронный запуск 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
, но это выглядит как худшее решение.Решение:
Применение:
file3:
File2:
File1:
источник
Есть несколько способов реализовать модули в Javascript, вот 2 самых популярных:
ES6 Модули
Браузеры пока не поддерживают эту систему модуляции, поэтому для использования этого синтаксиса вы должны использовать такой пакет, как webpack. В любом случае лучше использовать упаковщик, потому что он может объединить все ваши разные файлы в один (или пару связанных) файлов. Это позволит быстрее передавать файлы с сервера на клиент, поскольку с каждым HTTP-запросом связаны некоторые накладные расходы. Таким образом, уменьшая общий HTTP-запрос, мы улучшаем производительность. Вот пример модулей ES6:
CommonJS (используется в NodeJS)
Эта система модуляции используется в NodeJS. Вы в основном добавляете свои экспорты к объекту, который называется
module.exports
. Затем вы можете получить доступ к этому объекту черезrequire('modulePath')
. Важно понимать, что эти модули кэшируются, поэтому, если выrequire()
дважды определите модуль, он вернет уже созданный модуль.источник
Я пришел к этому вопросу, потому что искал простой способ поддерживать коллекцию полезных плагинов JavaScript. Увидев некоторые решения здесь, я придумал это:
Настройте файл с именем «plugins.js» (или extensions.js или все, что вы хотите). Храните ваши файлы плагинов вместе с этим одним основным файлом.
У plugins.js будет массив,
pluginNames[]
который мы будем перебиратьeach()
, а затем добавляем<script>
тег к заголовку для каждого плагина.<script src="js/plugins/plugins.js"></script>
НО:
Несмотря на то, что все плагины вставляются в тег head так, как они должны, они не всегда запускаются браузером при нажатии на страницу или обновлении.
Я обнаружил, что более надежно просто писать теги сценария в PHP include. Вы должны написать это только один раз, и это такая же работа, как вызов плагина с использованием JavaScript.
источник