В старых версиях JavaScript не было импорта, включения или требования, поэтому было разработано много разных подходов к этой проблеме.
Но с 2015 года (ES6) в JavaScript появился стандарт ES6 modules для импорта модулей в Node.js, который также поддерживается большинством современных браузеров .
Для совместимости со старыми браузерами можно использовать инструменты build и / или * .
Модули ES6
Модули ECMAScript (ES6) поддерживаются в Node.js начиная с версии 8.5 с флагом --experimental-modules
. Все задействованные файлы должны иметь расширение .mjs
.
// module.mjs
export function hello() {
return "Hello";
}
// main.mjs
import { hello } from 'module'; // or './module'
let val = hello(); // val is "Hello";
ECMAScript модули в браузерах
Браузеры поддерживают загрузку модулей ECMAScript напрямую (не требуются такие инструменты, как Webpack) с Safari 10.1, Chrome 61, Firefox 60 и Edge 16. Проверьте текущую поддержку на caniuse .
<script type="module">
import { hello } from './hello.mjs';
hello('world');
</script>
// hello.mjs
export function hello(text) {
const div = document.createElement('div');
div.textContent = `Hello ${text}`;
document.body.appendChild(div);
}
Подробнее на https://jakearchibald.com/2017/es-modules-in-browsers/
Динамический импорт в браузерах
Динамический импорт позволяет скрипту загружать другие скрипты по мере необходимости:
<script type="module">
import('hello.mjs').then(module => {
module.hello('world');
});
</script>
Подробнее на https://developers.google.com/web/updates/2017/11/dynamic-import
Node.js требуется
Старый стиль импорта модулей, все еще широко используемый в Node.js, это система module.exports / require .
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"
Существуют и другие способы включения JavaScript внешнего содержимого в браузерах, которые не требуют предварительной обработки.
AJAX Загрузка
Вы можете загрузить дополнительный скрипт с помощью вызова AJAX, а затем использовать eval
для его запуска. Это самый простой способ, но он ограничен вашим доменом из-за модели безопасности песочницы JavaScript. Использование eval
также открывает путь к ошибкам, взломам и проблемам безопасности.
Загрузка данных
Как и Dynamic Imports, вы можете загрузить один или несколько сценариев с помощью вызова fetch
, используя обещания для контроля порядка выполнения зависимостей сценариев, используя библиотеку Fetch Inject :
fetchInject([
'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})
JQuery Загрузка
Библиотека jQuery обеспечивает загрузку в одну строку :
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
Динамическая загрузка скриптов
Вы можете добавить тег HTML с URL-адресом скрипта в HTML. Чтобы избежать накладных расходов в jQuery, это идеальное решение.
Скрипт может даже находиться на другом сервере. Кроме того, браузер оценивает код. Тег <script>
может быть вставлен в веб-страницу <head>
или вставлен непосредственно перед закрывающим тегом </body>
.
Вот пример того, как это может работать:
function dynamicallyLoadScript(url) {
var script = document.createElement("script"); // create a script DOM node
script.src = url; // set its src to the provided URL
document.head.appendChild(script); // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
}
Эта функция добавит новый тег <script>
в конец раздела заголовка страницы, где атрибуту src
задается URL-адрес, который передается функции в качестве первого параметра.
Оба эти решения обсуждаются и иллюстрируются в JavaScript Madness: динамическая загрузка скриптов .
Обнаружение, когда скрипт был выполнен
Теперь есть большая проблема, о которой вы должны знать. Это означает, что вы дистанционно загружаете код . Современные веб-браузеры загружают файл и продолжают выполнять ваш текущий скрипт, потому что они загружают все асинхронно для повышения производительности. (Это относится как к методу 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, обеспечивать обратную совместимость для старых браузеров, объединять файлы , минимизировать, выполнять разбиение кода и т. д.