Как подключить библиотеку js
Перейти к содержимому

Как подключить библиотеку js

  • автор:

Как подключить библиотеку к файлу формата .js

Требуется подключить библиотеки jquery, GMap.js в файл MyScript.js (Формальное название для примера). Дело в том что все эти скрипты в html документе выглядят не очень красиво и легко путаешься, хотелось бы вынести пару троек скриптов и подключать и подгружать их. Как это можно сделать?

Отслеживать
задан 23 ноя 2015 в 13:06
710 2 2 золотых знака 9 9 серебряных знаков 24 24 бронзовых знака

В JS нет возможности сделать import. Как вариант, можно исходный код одного js-файла залить в другой. Но нужно быть осторожным, чтобы не было одинаковых глобальных переменных и названий функций.

23 ноя 2015 в 13:08

@LEQADA, ну зачем так категорично. Есть же require.js, browserify, webpack и много других хитрых штук.

23 ноя 2015 в 13:10
@DmitriySimushev, добавил в комментарий один обходной вариант в лоб. Но это всё же кастыль.
23 ноя 2015 в 13:11

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Начнем с того, что именно подразумевается под «эти скрипты в html документе выглядят не очень» Если вы прямо вставляете текст скрипта — то это неправильный выбор, следует делать так:

Учитывайте, что загрузка скрипта останавливает основной поток, поэтому либо ставьте их в конце (но внутри) либо с параметром async .

Если же все-таки вы это знаете, но вам хочется динамически загружать скрипты из своего, то для этого можно либо воспользоваться библиотеками, например Require.JS или самому написать вот такое:

var script = document.createElement('script'); script.onload = function () < // Скрипт был загружен >; document.head.appendChild(script); script.src = 'урл к вашему файлу'; 

Есть еще один путь, т.к. у вас jQuery — ее можно использовать в качестве загрузчика — у нее есть такой функционал:

$.getScript( "ajax/test.js", function( data, textStatus, jqxhr ) < // Загрузили >); 

Т.к. у вас несколько скриптов, необходимо их загружать с учетом зависимостей.

В jQuery можно сделать так:

$.when( $.getScript( "script1.js" ), $.getScript( "script2.js" ), $.Deferred(function( deferred )< $( deferred.resolve ); >) ).done(function()< // все загрузили >); 

Подключение JS к HTML: 2 простых способа

JavaScript — популярный язык программирования, который позволяет добавить веб-сайту интерактивности и динамичности. Чтобы использовать возможности этого языка, сперва его нужно подключить к HTML-документу. В этой статье мы рассмотрим 2 варианта, как добавить JavaScript в HTML, а также обсудим, как правильно это сделать, чтобы не замедлить загрузку сайта.

Способы подключения JavaScript к HTML

Чтобы дать понять браузеру, что ему необходимо выполнить некоторый js-код (также его называют «сценарий» или «скрипт»), на страницу добавляется парный тег script. Все, что находится в пределах этого тега, браузер обрабатывает как JavaScript-код. Тег script обычно помещают либо в теге head, либо в body.

     Подключение js к html 

Есть 2 известных способа, как подключить JS к HTML:

  • Размещение кода прямо в HTML-документе.
  • С помощью внешнего js-файла.

JavaScript-код на странице

Самый элементарный способ, как установить скрипт — пишем код прямо на HTML-странице между тегами script. Обычно такой метод используют для небольших сценариев. В практике этот вариант популярен для добавления на веб-ресурс различных счетчиков статистики, аналитики и иных js-кодов для взаимодействия со сторонними ресурсами.

В нашем случае мы рассмотрим однострочный код, который будет отображать в браузере модальное диалоговое окно с простой фразой «Привет! Я JavaScript!». В этом нам поможет JavaScript-функция alert(). В качестве параметра этой функции передадим наш приветственный текст.

     Подключение js к html  .   

Увидеть результат выполнения вышеуказанного сценария можно, нажав на кнопку:

Внешний файл JavaScript

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

Предположим, у нас есть файл script.js с готовым сценарием. Чтобы подключить этот файл в HTML, разместим там следующий код:

Вставим его либо в заголовок (head), либо в тело документа (body).

О том, в каком конкретно месте лучше подключить js-файл, мы поговорим далее.

Наш HTML-код будет выглядеть следующим образом:

     Подключение js к html  . 

Хорошие практики подключения JavaScript к HTML

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

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

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

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

Порядок исполнения js-файлов

Загружая веб-страницу, браузер читает ее сверху вниз, выстраивая DOM-дерево из содержащихся на ней элементов. Тег script, установленный в заголовке head, будет выполнен в начале загрузки HTML-документа.

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

Крупные JavaScript-файлы в заголовке являются одной из причин, почему сайт может долго не отображаться. Как запустить JavaScript на сайте, избежав подобной проблемы? Один из вариантов решения — подключить js-код перед закрывающим тегом body.

     Подключение js к html . 

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

Как же наиболее эффективно повлиять на увеличение скорости загрузки? Самое правильное и современное решение — асинхронная загрузка.

Асинхронная загрузка JavaScript

Благодаря асинхронной загрузке, подключенные в HTML внешние js-файлы не блокируют построение DOM-дерева. Чтобы указать js-файлу загружаться асинхронно, тегу script необходимо добавить один из следующих атрибутов: async или defer.

Рассмотрим, как использовать скрипты с этими атрибутами, и выделим их особенности.

Атрибут async

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

Порядок расположения js-файлов с этим атрибутом в HTML относительно друг друга не имеет значения — они выполняются обособленно. Этот момент нужно учесть, когда мы собираемся подключить такой скрипт на сайт: файлы с атрибутом async не должны зависеть один от одного, так как невозможно знать, в каком порядке они будут выполняться, что может привести к ошибкам на ресурсе.

Атрибут defer

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

Еще одно отличие этих атрибутов заключается в том, что после того, как такой файл с defer загрузился, браузер не сможет запустить скрипт до тех пор, пока HTML-документ не будет полностью обработан.

Подытожив, сравним особенности исследуемых атрибутов, выделив их в отдельную таблицу:

Не блокируют рендеринг содержимого Важен порядок расположения на странице Выполняются строго после обработки документа
async Да Нет. Загружаются и отрабатываются независимо Нет. Может загрузиться до или после, в зависимости от размеров самого js-кода и документа
defer Да Да. Выполняются в порядке размещения в документе Да

Получилось ли у вас подключить JS к HTML? Поделитесь в комментариях!

Модули JavaScript

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Это руководство содержит всю необходимую информацию для начала работы с модулями JavaScript.

Модули: история вопроса

Сначала программы на JavaScript были небольшими — в прежние времена они использовались для изолированных задач, добавляя при необходимости немного интерактивности веб-страницам, так что большие скрипты в основном не требовались. Прошло несколько лет, и вот мы уже видим полномасштабные приложения, работающие в браузерах и содержащие массу кода на JavaScript; кроме того, язык стал использоваться и в других контекстах (например, Node.js).

Таким образом, в последние годы появились причины на то, чтобы подумать о механизмах деления программ на JavaScript на отдельные модули, которые можно импортировать по мере необходимости. Node.js включал такую возможность уже давно, кроме того, некоторые библиотеки и фреймворки JavaScript разрешали использование модулей (например, CommonJS и основанные на AMD системы модулей типа RequireJS, а позднее также Webpack и Babel).

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

Встроенная обработка модулей JavaScript связана с инструкциями import и export , их поддержка браузерами показана в следующих таблицах.

Совместимость с браузерами

javascript.statements.import

BCD tables only load in the browser

javascript.statements.export

BCD tables only load in the browser

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

Для того, чтобы продемонстрировать использование модулей, мы создали простой набор примеров, который вы можете найти на GitHub. В этих примерах мы создаём элемент на веб-странице и затем рисуем различные фигуры на нём (и выводим информацию об этом).

Примеры довольно тривиальны, но они намеренно сделаны простыми для ясной демонстрации модулей.

Примечание: Если вы хотите скачать примеры и запустить их локально, вам нужно будет запустить их через локальный веб-сервер.

Базовая структура примера

В первом примере (см. директорию basic-modules) у нас следующая структура файлов:

index.html main.js modules/ canvas.js square.js

Примечание: Все примеры в этом руководстве в основном имеют одинаковую структуру.

Давайте разберём два модуля из директории modules:

  • canvas.js — содержит функции, связанные с настройкой canvas:
    • create() — создаёт холст заданной ширины width и высоты height внутри -обертки с указанным id и помещённой в родителя parent . Результатом выполнения функции будет объект, содержащий 2D-контекст холста и id обертки.
    • createReportList() — создаёт неупорядоченный список, добавленный внутри указанного элемента-обёртки, который можно использовать для вывода данных отчёта. Возвращает id списка.
    • name — переменная со строковым значением ‘square’.
    • draw() — функция, рисующая квадрат на указанном холсте с заданными размером, положением и цветом. Возвращает объект, содержащий размер, положение и цвет квадрата.
    • reportArea() — функция, которая выводит посчитанную площадь квадрата в указанный список отчета.
    • reportPerimeter() — функция, которая выводи посчитанный периметр квадрата в указанный список отчета.

    Взгляд со стороны — .mjs против .js

    В этой статье мы используем расширение .js для файлов наших модулей, но в других источниках вы можете встретить расширение .mjs . Например, в документации движка V8 используется .mjs . Причины следующие:

    • Это полезно для ясности, то есть дает понять, какие файлы являются модулями, а какие — обычными JavaScript-файлами.
    • Это гарантирует, что файлы вашего модуля будут проанализированы как модуль средами выполнения, такими как Node.js, и инструментами сборки, такими как Babel.

    Тем не менее, мы решили продолжать использовать .js , по крайней мере на данным момент. Чтобы модули корректно работали в браузере, вам нужно убедиться, что ваш сервер отдаёт их с заголовком Content-Type , который содержит JavaScript MIME type такой как text/javascript . В противном случае вы получете ошибку проверки MIME type — «The server responded with a non-JavaScript MIME type», и браузер не сможет запустить ваш JavaScript. Большинство серверов уже имеют правильный тип для .js -файлов, но ещё не имеют нужного MIME type для .mjs -файлов. Серверы, которые уже отдают .mjs файлы корректно, включают в себя GitHub Pagesи http-сервер для Node.js.

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

    В целях обучения и переносимости на разные платформы мы решили остановится на .js .

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

    Также стоит отметить, что:

    • Некоторые инструменты могут никогда не добавить поддержку .mjs , например, TypeScript.
    • атрибут используется для обозначения того, что файл является модулем. Вы увидите примеры использования данного атрибута ниже.

    Экспорт функциональности модуля

    Первое, что нужно сделать, чтобы получить доступ к функциональности модуля, — экспортировать его. Это делается с помощью инструкции export .

    Самый простой способ использовать экспорт — поместить конструкцию export перед любыми элементами, которые вы хотите экспортировать из модуля, например:

    export const name = "square"; export function draw(ctx, length, x, y, color)  ctx.fillStyle = color; ctx.fillRect(x, y, length, length); return  length: length, x: x, y: y, color: color, >; > 

    Вы можете экспортировать var -, let -, const -переменные, и — как мы увидим позже — классы. Они должны быть в верхней области видимости, вы не можете использовать export внутри функции, например.

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

    export  name, draw, reportArea, reportPerimeter >; 

    Импорт функциональности в ваш скрипт

    После того, как вы экспортировали некоторые части из своего модуля, вам необходимо импортировать их в свой скрипт, чтобы иметь возможность использовать их. Самый простой способ сделать это:

    import  name, draw, reportArea, reportPerimeter > from "./modules/square.js"; 

    Используйте конструкцию import , за которой следует разделенный запятыми список функций, которые вы хотите импортировать, заключённый в фигурные скобки, за которым следует ключевое слово from, за которым следует путь к файлу модуля — путь относительно корня сайта, который для нашего примера basic-modules будет равен /js-examples/modules/basic-modules .

    Однако, мы написали путь немного иначе — мы используем ( . ) синтаксис, означающий «текущую директорию», за которым следует путь к файлу, который мы пытаемся найти. Это намного лучше, чем каждый раз записывать весь относительный путь, поскольку он короче и делает URL-адрес переносимым — пример все равно будет работать, если вы переместите его в другое место в иерархии сайта.

    /js-examples/modules/basic-modules/modules/square.js
    ./modules/square.js

    Вы можете найти подобные строки кода в файле main.js .

    Примечание: В некоторых модульных системах вы можете опустить расширение файла и начальные / , ./ , or ../ (например ‘modules/square’ ). Это не работает в нативных JavaScript-модулях.

    После того, как вы импортировали функции в свой скрипт, вы можете использовать их так же, как если бы они были определены в этом же файле. Следующий пример можно найти в main.js , сразу за строками импорта:

    let myCanvas = create("myCanvas", document.body, 480, 320); let reportList = createReportList(myCanvas.id); let square1 = draw(myCanvas.ctx, 50, 50, 100, "blue"); reportArea(square1.length, reportList); reportPerimeter(square1.length, reportList); 

    Примечание: Хотя импортированные функции доступны в файле, они доступны только для чтения. Вы не можете изменить импортированную переменную, но вы всё равно можете изменять свойства у const -переменных. Кроме того, переменные импортируется как «live bindings» — это означает, что они могут меняться по значению, даже если вы не можете изменить привязку, в отличие от const .

    Добавление модуля на HTML-страницу

    Далее нам необходимо подключить модуль main.js на нашу HTML-страницу. Это очень похоже на то, как мы подключаем обычный скрипт на страницу, с некоторыми заметными отличиями.

    script type="module" src="main.js"> script> 

    Вы также можете встроить скрипт модуля непосредственно в HTML-файл, поместив JavaScript-код внутрь -элемента:

    script type="module">/* код JavaScript модуля *//script> 

    Скрипт, в который вы импортируете модуль, в основном действует как модуль верхнего уровня. Если вы упустите это, то Firefox, например, выдаст ошибку «SyntaxError: import declarations may only appear at top level of a module».

    Вы можете использовать import и export инструкции только внутри модулей, внутри обычных скриптов они работать не будут.

    Другие отличия модулей от обычных скриптов

    • Вы должны быть осторожны во время локального тестирование — если вы попытаетесь загрузить файл HTML локально (то есть по file:// URL), вы столкнётесь с ошибками CORS из-за требований безопасности JavaScript-модулей. Вам нужно проводить тестирование через сервер.
    • Также обратите внимание, что вы можете столкнуться с отличным от обычных файлов поведением кода в модулях. Это происходит из-за того, что модули используют strict mode автоматически.
    • Нет необходимости использовать атрибут defer (см. атрибуты элемента) при загрузке модуля, модули являются deferred по умолчанию.
    • Модули выполняются только один раз, даже если на них есть ссылки в нескольких тэгах.
    • И последнее, но не менее важное: функциональность модуля импортируются в область видимости одного скрипта, она недоступны в глобальной области видимости. Следовательно, вы сможете получить доступ к импортированным частям модуля только в скрипте, в который он импортирован, и, например, вы не сможете получить к нему доступ из консоли JavaScript. Вы по-прежнему будете получать синтаксические ошибки в DevTools, но вы не сможете использовать некоторые методы отладки, которые, возможно, ожидали использовать.

    Экспорт по умолчанию против именованного экспорта

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

    Существует также тип экспорта, который называется экспорт по умолчанию — он существует для удобного экспорта основной функции, а также помогает модулям JavaScript взаимодействовать с существующими модульными системами CommonJS и AMD (это хорошо объясняется в статье Джейсона Орендорфа ES6 в деталях: Модули, ищите по ключевому слову «Default exports»).

    Давайте посмотрим на пример и объясним, как это работает. В модуле square.js из нашего примера вы можете найти функцию randomSquare() , которая создаёт квадрат со случайным цветом, размером и координатами. Мы хотим экспортировать эту функции по умолчанию, поэтому в конце файла пишем следующее:

    export default randomSquare; 

    Обратите внимание на отсутствие фигурных скобок.

    Кстати, можно было бы определить функцию как анонимную и добавить к ней export default :

    export default function(ctx)  . > 

    В нашем файле main.js мы импортируем функцию по умолчанию, используя эту строку:

    import randomSquare from "./modules/square.js"; 

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

    import  default as randomSquare > from "./modules/square.js"; 

    Примечание: «as» синтаксис для переименования экспортируемых элементов поясняется ниже в разделе Переименование импорта и экспорта.

    Как избежать конфликтов имён

    Пока что наши модули для рисования фигур на холсте работают нормально. Но что произойдёт, если мы попытаемся добавить модуль, который занимается рисованием другой фигуры, например круга или треугольника? С этими фигурами, вероятно, тоже будут связаны такие функции, как draw() , reportArea() и т.д.; если бы мы попытались импортировать разные функции с одним и тем же именем в один и тот же файл модуля верхнего уровня, мы бы столкнулись с конфликтами и ошибками.

    К счастью, есть несколько способов обойти это. Мы рассмотрим их в следующих разделах.

    Переименование импорта и экспорта

    Можно изменять имя функциональности в целевом модуле с помощью ключевого слова as внутри фигурных скобок инструкций import и export .

    Так, например, оба следующих элемента будут выполнять одну и ту же работу, хотя и немного по-разному:

    // внутри module.js export  function1 as newFunctionName, function2 as anotherNewFunctionName >; // внутри main.js import  newFunctionName, anotherNewFunctionName > from "./modules/module.js"; 
    // внутри module.js export  function1, function2 >; // внутри main.js import  function1 as newFunctionName, function2 as anotherNewFunctionName, > from "./modules/module.js"; 

    Давайте посмотрим на реальный пример. В нашей renaming директории вы увидите ту же модульную систему, что и в предыдущем примере, за исключением того, что мы добавили модули circle.js и triangle.js для рисования кругов и треугольников и создания отчетов по ним.

    Внутри каждого из этих модулей у нас есть функции с одинаковыми именами, которые экспортируются, и поэтому у каждого из них есть один и тот же оператор export внизу файла:

    export  name, draw, reportArea, reportPerimeter >; 

    Если бы в main.js при их импорте мы попытались использовать

    import  name, draw, reportArea, reportPerimeter > from "./modules/square.js"; import  name, draw, reportArea, reportPerimeter > from "./modules/circle.js"; import  name, draw, reportArea, reportPerimeter > from "./modules/triangle.js"; 

    то браузер выдал бы ошибку — «SyntaxError: redeclaration of import name» (Firefox).

    Вместо этого нам нужно переименовать импорт, чтобы он был уникальным:

    import  name as squareName, draw as drawSquare, reportArea as reportSquareArea, reportPerimeter as reportSquarePerimeter, > from "./modules/square.js"; import  name as circleName, draw as drawCircle, reportArea as reportCircleArea, reportPerimeter as reportCirclePerimeter, > from "./modules/circle.js"; import  name as triangleName, draw as drawTriangle, reportArea as reportTriangleArea, reportPerimeter as reportTrianglePerimeter, > from "./modules/triangle.js"; 

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

    // внутри square.js export  name as squareName, draw as drawSquare, reportArea as reportSquareArea, reportPerimeter as reportSquarePerimeter, >; 
    // внутри main.js import  squareName, drawSquare, reportSquareArea, reportSquarePerimeter, > from "./modules/square.js"; 

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

    Создание объекта модуля

    Вышеупомянутый способ работает нормально, но он немного запутан и многословен. Существует решение получше — импортировать функции каждого модуля внутри объекта модуля. Для этого используется следующая синтаксическая форма:

    import * as Module from "./modules/module.js"; 

    Эта конструкция берёт все экспорты, доступные внутри module.js и делает их доступными в качестве свойств объекта Module , фактически давая ему собственное пространство имен. Так например:

    .function1(); Module.function2(); 

    Опять же, давайте посмотрим на реальный пример. Если вы посмотрите на нашу директорию module-objects, вы снова увидите тот же самый пример, но переписанный с учётом преимуществ этого нового синтаксиса. В модулях все экспорты представлены в следующей простой форме:

    export  name, draw, reportArea, reportPerimeter >; 

    С другой стороны, импорт выглядит так:

    import * as Canvas from "./modules/canvas.js"; import * as Square from "./modules/square.js"; import * as Circle from "./modules/circle.js"; import * as Triangle from "./modules/triangle.js"; 

    В каждом случае теперь вы можете получить доступ к импорту модуля под указанным свойством объекта, например:

    let square1 = Square.draw(myCanvas.ctx, 50, 50, 100, "blue"); Square.reportArea(square1.length, reportList); Square.reportPerimeter(square1.length, reportList); 

    Таким образом, теперь вы можете написать код точно так же, как и раньше (при условии, что вы включаете имена объектов там, где это необходимо), и импорт будет намного более аккуратным.

    Модули и классы

    Как мы намекали ранее, вы также можете экспортировать и импортировать классы — это ещё один способ избежать конфликтов в вашем коде, и он особенно полезен, если у вас уже есть код модуля, написанный в объектно-ориентированном стиле.

    Вы можете увидеть пример нашего модуля для рисования фигур, переписанного с помощью классов ES в нашей директории classes. В качестве примера, файл square.js теперь содержит всю свою функциональность в одном классе:

    class Square  constructor(ctx, listId, length, x, y, color)  . > draw()  . > . > 

    который мы затем экспортируем:

    export  Square >; 

    Далее в main.js , мы импортируем его так:

    import  Square > from "./modules/square.js"; 

    А затем используем импортированный класс, чтобы нарисовать наш квадрат:

    let square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, "blue"); square1.draw(); square1.reportArea(); square1.reportPerimeter(); 

    Агрегирующие модули

    Возможны случаи, когда вы захотите объединить модули вместе. У вас может быть несколько уровней зависимостей, где вы хотите упростить вещи, объединив несколько подмодулей в один родительский модуль. Это возможно с использованием следующего синтаксиса экспорта в родительском модуле:

    export * from "x.js"; export  name > from "x.js"; 

    Для примера посмотрите на нашу директорию module-aggregation. В этом примере (на основе нашего предыдущего примера с классами) у нас есть дополнительный модуль с именем shapes.js , который собирает функциональность circle.js , square.js и triangle.js вместе. Мы также переместили наши подмодули в дочернюю директорию внутри директории modules под названием shape . Итак, структура модуля в этом примере:

    modules/ canvas.js shapes.js shapes/ circle.js square.js triangle.js

    В каждом из подмодулей экспорт имеет одинаковую форму, например:

    export  Square >; 

    Далее идет агрегирование. Внутри shapes.js , мы добавляем следующие строки:

    export  Square > from "./shapes/square.js"; export  Triangle > from "./shapes/triangle.js"; export  Circle > from "./shapes/circle.js"; 

    Они берут экспорт из отдельных подмодулей и фактически делают их доступными из модуля shape.js .

    Примечание: Экспорты, указанные в shape.js , по сути перенаправляются через файл и на самом деле там не существуют, поэтому вы не сможете написать какой-либо полезный связанный код внутри того же файла.

    Итак, теперь в файле main.js мы можем получить доступ ко всем трём классам модулей, заменив:

    import  Square > from "./modules/square.js"; import  Circle > from "./modules/circle.js"; import  Triangle > from "./modules/triangle.js"; 

    на единственную строку кода:

    import  Square, Circle, Triangle > from "./modules/shapes.js"; 

    Динамическая загрузка модулей

    Самая свежая возможность JavaScript-модулей доступная в браузерах, — это динамическая загрузка модулей. Это позволяет вам динамически загружать модули только тогда, когда они необходимы, вместо того, чтобы загружать всё заранее. Это даёт очевидные преимущества в производительности — давайте продолжим читать и посмотрим, как это работает.

    Поддержка динамической загрузки модулей позволяет вызывать import() в качестве функции, передав ей аргументом путь к модулю. Данный вызов возвращает Promise , который резолвится объектом модуля (см. Создание объекта модуля), предоставляя вам доступ к экспорту указанного модуля, например:

    import("./modules/myModule.js").then((module) =>  // Делаем что-нибудь с импортированным модулем >); 

    Давайте посмотрим на пример. В директории dynamic-module-imports у нас есть ещё один пример, основанный на примере наших классов. Однако на этот раз мы ничего не рисуем на холсте при загрузке страницы. Вместо этого мы добавляем на страницу три кнопки — «Circle», «Square» и «Triangle», которые при нажатии динамически загружают требуемый модуль, а затем используют его для рисования указанной фигуры.

    В этом примере мы внесли изменения только в наши index.html и main.js — экспорт модуля остается таким же, как и раньше.

    Далее в main.js мы взяли ссылку на каждую кнопку, используя вызов document.querySelector() :

    let squareBtn = document.querySelector(".square"); 

    Затем мы добавляем обработчик событий на каждую кнопку, чтобы при нажатии соответствующий модуль динамически загружался и использовался для рисования фигуры:

    .addEventListener("click", () =>  import("./modules/square.js").then((Module) =>  let square1 = new Module.Square( myCanvas.ctx, myCanvas.listId, 50, 50, 100, "blue", ); square1.draw(); square1.reportArea(); square1.reportPerimeter(); >); >); 

    Обратите внимание: поскольку выполнение Promise возвращает объект модуля, класс затем становится подкомпонентом объекта, поэтому теперь для получения доступа к конструктору нам нужно добавить к нему Module. , например Module.Square(. ) .

    Устранение проблем

    Вот несколько советов, которые могут помочь вам, если вам не удаётся заставить ваши модули работать. Не стесняйтесь дополнять список, если найдете что-то ещё!

    • Мы упоминали об этом раньше, но повторяем: .js -файлы должны быть загружены с MIME-type равным text/javascript (или любым другим JavaScript-совместимым MIME-type, но text/javascript является рекомендованным), в противном случае вы получите ошибку проверки MIME-type, например — «The server responded with a non-JavaScript MIME type».
    • Если вы попытаетесь загрузить HTML-файл локально (то есть по ссылке file:// ), вы столкнетесь с ошибками CORS из-за требований безопасности JavaScript-модулей. Вам нужно проводить тестирование через сервер. GitHub pages идеально для этого подходят, так как отдают .js -файлы с нужным MIME-type.
    • Поскольку .mjs — нестандартное расширение файла, некоторые операционные системы могут его не распознать или попытаться заменить на что-то другое. Например, мы обнаружили, что macOS незаметно добавляла .js в конец файлов .mjs , а затем автоматически скрывала расширение файла. Таким образом, все наши файлы на самом деле имели название типа x.mjs.js . Когда мы отключили автоматическое скрытие расширений файлов и научили macOS принимать .mjs , всё стало в порядке.

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

    • Использование JavaScript-модулей в вебе, от Эдди Османи и Матиаса Байненса (англ.)
    • Глубокое погружение в ES-модули в картинках, от Лина Кларка на Hacks blog (англ.)
    • Глубокое погружение в ES-модули в картинках, перевод на русский язык от «Веб-стандартов»
    • ES6 в деталях: Модули, статья от Джейсона Орендорфа на Hacks blog (англ.)
    • Изучаем JS: Модули (англ), книга Акселя Раушмайера (англ.)
    • « Предыдущая статья

    Как добавить JavaScript без ожирения сайта

    JavaScript — основной инструмент оживления страниц. Но, думая, как вставить Javascript в HTML, важно держать в уме еще одну мысль: как не переборщить.

    Анатолий Ализар

    Анатолий Ализар

    Пишет про разработку в Skillbox Media. Работал главным редактором сайта «Хабрахабр», ведёт корпоративные блоги.

    Как добавить JavaScript в HTML

    Тег

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

    Код JavaScript в тексте страницы

    Чтобы встроить JavaScript в HTML, открываем файл HTML в любом текстовом редакторе, добавляем теги , между ними пишем код программы. Затем сохраняем файл (например, skillbox.htm).

    Код

    Внешний файл .js

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

    Для подключения внешнего файла мы опять используем открывающий и закрывающий теги , но между ними указываем не код программы, а путь к файлу с расширением .js, где записан этот код программы.

    В нашем примере программу alert(«Привет, Skillbox») мы сохраняем в отдельный файл skill.js, а относительный или абсолютный путь к нему прописываем между тегами с атрибутом src=»».

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

    В чем причина?

    Дело в том, что загрузка скриптов влияет на самую главную метрику производительности: время до появления интерактивности (Time to Interactive). Например, изображения на странице практически не влияют на эту метрику, потому что они не блокируют загрузку элементов интерфейса, а вот скрипты выполняются в основном потоке, то есть находятся на критичном пути рендеринга. Поэтому ни в коем случае нельзя безгранично раздувать количество скриптов на странице. Если пользователь с настольного компьютера или ноутбука еще кое-как загрузит страницу, то пользователь на смартфоне может ее не дождаться. Через десять секунд ожидания он просто закроет страницу.

    Оптимизация JavaScript на странице

    Бюджет

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

    Порядок исполнения

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

    Поэтому есть смысл переносить в конец страницы ссылки на некритичные скрипты, такие как счетчики, скрипты аналитики и реклама.

    Асинхронная загрузка

    Более грамотный способ решить проблему с загрузкой «медленных» внешних скриптов — асинхронная загрузка с помощью атрибута async. Если с тегом указан такой атрибут, то браузер не будет ждать загрузки и выполнения этого скрипта, прежде чем показать оставшуюся часть страницы.

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

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

    Читайте также:

    • Как адаптировать сайт под разные разрешения
    • Лучшее из любимого: 13 отличных статей о Computer Science
    • Какой язык программирования учить новичку. Выбираем JavaScript

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *