Введение в NativeScript
В этой статье мы рассмотрим NativeScript, платформу с открытым исходным кодом для создания мобильных приложений на JavaScript. В конце статьи вы должны будите иметь довольно хорошее представление о том, что такое NativeScript, как он работает и какие технологии он использует. Помимо этого, мы также получим ответы на общие вопросы, которые могут возникнуть при изучении новой технологии, например, чем она отличается от альтернатив, таких как Cordova и React Native, и о том, как Telerik участвует в проекте.
1. Что такое NativeScript?
2. Плюсы
3. Против
4. Как это работает?
NativeScript состоит из виртуальной машины JavaScript, среды выполнения и бридж модуля. Виртуальная машина JavaScript интерпретирует и выполняет код JavaScript. Затем бридж модуль переводит вызовы на вызовы API для конкретной платформы и возвращает результат вызывающему объекту. Проще говоря, NativeScript предоставляет разработчикам способ управлять собственной платформой с помощью JavaScript вместо Objective-C на iOS или Java на Android.
5. Какие технологии используются?
С NativeScript вы используете XML для описания пользовательского интерфейса приложения, CSS для стилизации и JavaScript для добавления функциональности.
Вы можете использовать TypeScript с Angular 2, если вы предпочитаете использовать фреймворк для разработки кода JavaScript.
Для стилизации NativeScript использует только подмножество CSS. Это означает, что не все функции CSS, доступные в среде браузера, могут использоваться. Например, вы не можете использовать floats или атрибуты позиции. Ниже приведен полный список поддерживаемых свойств CSS. Как и в браузере, вы можете добавлять стили, применимые ко всему приложению, к определенным страницам или только к определенному компоненту пользовательского интерфейса. Если вы предпочитаете использовать Sass, вы можете установить плагин NativeScript Dev Sass.
Для описания структуры пользовательского интерфейса вы используете XML. Каждая страница в приложении должна быть в собственном XML-файле. NativeScript поставляется с предустановленными виджетами или компонентами пользовательского интерфейса, которые вы можете использовать для создания пользовательского интерфейса приложения. Некоторые из этих компонентов похожи на различные HTML-элементы, которые вы используете в браузере.
Другое дело, что компоненты также служат в качестве шаблонов. Если вы знакомы с шаблонами таких библиотек, как Handlebars или Mustache, вы должны быть знакомы со следующим синтаксисом:
Наконец, есть плагины, которые позволяют вам получить доступ к аппаратным средствам и особенностям платформы. NativeScript поставляется с предустановленным плагином камеры. Это позволяет получить доступ к камере устройства и делать снимки. Затем вы можете сохранить локальный путь к фотографии в своем приложении для последующего использования. Такие специфичные для платформы функции, как социальный обмен, также могут быть использованы при установке плагинов, например плагин NativeScript Social Share Plugin.
6. Какие приложения вы можете создать?
Благодаря естественному характеру NativeScript вы можете создавать с ним практически любое приложение. Вот несколько примеров приложений, которые можно создавать с помощью NativeScript:
Когда дело доходит до видов приложений, которые можно создавать с помощью NativeScript, единственными ограничивающими факторами являются производительность и доступность плагина. У написания собственных мобильных приложений на JavaScript есть и своя цена: вы не можете рассчитывать на создание приложений, требующих высокой производительности. Примеры включают игры со сложной графикой и анимацией, приложения с большим количеством движущихся частей и фоновые процессы.
Другим ограничением является доступность плагина. Большинство разработчиков приходят к NativeScript из веб-разработки. Это означает, что большинство из них не знакомы или имеют ограниченное знание API-интерфейсов о нативной платформе, которые могут быть использованы для создания плагинов для доступа к аппаратным средствам устройства или специфичным для платформы функциям, таким как контакты или обмен сообщениями.
Если вы хотите узнать больше о том, какие приложения вы можете создать с помощью NativeScript, вы можете проверить страницу App Showcases. Большинство приложений, перечисленных в них, публикуются как в Google Play Store, так и в Apple Store. Это означает, что вы можете установить его и запустить на своем устройстве, чтобы понять, какие приложения созданы с использованием NativeScript и как они работают.
7. Сравнение NativeScript с гибридными фреймворками
Если вы не новичок в разработке мобильных мобильных приложений, возможно, вы уже успели столкнуться с такими фреймворками, как Cordova и React Native. NativeScript связан с этими двумя фреймворками, поскольку они оба направлены на решение проблемы «Write once, run at» в области разработки мобильных приложений. Теперь давайте посмотрим на каждый из этих фреймворков:
| Cordova | React Native | NativeScript | |
|---|---|---|---|
| Создатель | Nitobi; Позже приобрел Adobe Systems | Telerik | |
| UI | HTML | Компоненты пользовательского интерфейса переводятся в их нативные экземпляры | Компоненты пользовательского интерфейса переводятся в их нативные экземпляры |
| Можно проверить на | Браузер, эмулятор, устройство | Эмулятор, устройство | Эмулятор, устройство |
| Код с | HTML, CSS, JavaScript | Компоненты пользовательского интерфейса, JavaScript, подмножество CSS | Компоненты пользовательского интерфейса, подмножество CSS, JavaScript |
| Нативный функционал | Через плагины | Нативные модули | Доступ к собственному API через JavaScript |
| Развертывается | Android, iOS, Ubuntu, Windows, OS X, Blackberry 10 | Android и iOS. Windows Universal и Samsung Tizen в ближайшее время | Android и iOS. Windows Universal скоро появится |
| Библиотеки JavaScript и фреймворки | Любая внешняя библиотека или структура (например, Angular, Ember) | Любая библиотека, которая не зависит от браузера | Любая библиотека, которая не зависит от браузера |
| Схема кодирования | Любая инфраструктура front-end может использоваться для структурирования кода | Разметка пользовательского интерфейса, JavaScript и CSS объединяются в один файл по умолчанию | Шаблон MVVM / MVC |
| Как выполняется код JavaScript | WebView | JavaScriptCore Engine для выполнения кода приложения на Android и iOS | Webkit JavaScriptCore для выполнения кода приложения на iOS и JavaScript на V8 JavaScript на Android |
Кто-то может придумать лучшее имя для фреймворков, таких как React Native и NativeScript в будущем. Но пока давайте классифицировать их как «Нативные гибридные фреймворки», потому что они оба используют JavaScript для разработки приложений, и оба они предлагают возможности и производительность для пользователей.
8. Как Telerik участвует в проекте?
Платформа Telerik предоставляет разработчикам инструменты, необходимые им для легкого проектирования, сборки, тестирования, развертывания, управления и оценки производительности приложений NativeScript. Вот несколько примеров инструментов, которые они предлагают:
Пользовательский интерфейс Telerik для NativeScript представляет собой набор компонентов для создания пользовательского интерфейса приложения. В NativeScript уже есть бесплатные компоненты пользовательского интерфейса, но есть и платные компоненты пользовательского интерфейса, такие как Chart и Calendar, которые вы можете использовать только при покупке у Telerik.
9. Следующие шаги
Если вы хотите узнать больше о NativeScript, я рекомендую проверить обратить внимание на следующие ресурсы:
Вывод
В этой статье вы узнали о самых основах NativeScript. Как вы видели, NativeScript является хорошим вариантом для создания мобильных приложений с использованием навыков, которые у вас уже есть как у веб-разработчика. Я надеюсь, что эта статья предоставила вам необходимые знания, чтобы помочь вам решить, подходит ли NativeScript для вас.
Нативные ECMAScript модули — первый обзор
В этой статье хочу поделиться переводом статьи о нативных ECMAScript модулях, которые все больше и больше обсуждаются среди фронтендеров. Javascript ранее никогда не поддерживал нативно работу с модулями, и нам, фронтендерам, всегда приходилось использовать дополнительные инструменты для работы с модулями. Но вы только представьте, что в скором времени не нужно будет использовать Webpack для создания бандлов модулей. Представьте мир, в котором браузер будет собирать все за вас. Подробнее об этих перспективах я и хочу рассказать.
В 2016 году в браузеры и Nodejs было добавлено много интересных фич и полезностей из новых стандартов, в частности спецификации ECMAScript 2015. Сейчас мы сталкиваемся с ситуацией, когда поддержка среди браузеров близка к 100%:
Также фактически в стандарт введены ECMAScript модули (часто называют ES/ES6 модули). Это единственная часть спецификации, которая требовала и требует наибольшего времени для реализации, и ни один браузер пока не выпустил их в стабильной версии.
Недавно в Safari 19 Technical Preview и Edge 15 добавили реализацию модулей без использования флагов. Уже близится то время, когда мы можем отказаться от использования привычных всем бандлов и транспиляции модулей.
Чтобы лучше понять, как мир фронтенда пришел к этому, давайте начнем с истории JS модулей, а затем взглянем на текущие преимущества и реализации ES6 модулей.
Немного истории
Было много способов подключения модулей. Приведу для примера наиболее типичные из них:
1. Просто длинный код внутри script тега. Например:
2. Разделение логики между файлами и подключение их с помощью тегов script:
3. Модуль как функция (например: модуль функция, которая возвращает что-то; самовызывающаяся функция или функция конструктор) + Application файл/модель, которые будут точкой входа для приложения:
Ко всему этому Frontend сообщество изобрело много разновидностей и новых способов, которые добавляли разнообразие в этот праздник анархии.
Основная идея заключается в том, чтобы обеспечить систему, которая позволит вам просто подключить одну ссылку JS файла, вот так:
Но всё свелось к тому, что разработчики выбрали сторону бандлеров — систем сборки кода. Далее предлагается рассмотреть основные реализации модулей в JavaScript.
Асинхронное определение модуля (AMD)
Такой подход широко реализуется в библиотеке RequireJS и в инструментах, таких как r.js для создания результирующего бандла. Общий синтаксис:
CommonJS
Это основной формат модулей в Node.js экосистеме. Одним из основных инструментов для создания бандлов для клиентских устройств является Browserify. Особенность этого стандарта — обеспечение отдельной области видимости для каждого модуля. Это позволяет избежать непреднамеренной утечки в глобальную область видимости и глобальных переменных.
ECMAScript модули (ака ES6/ES2015/нативные JavaScript модули)
Еще один способ работы с модулями пришел к нам с ES2015. В новом стандарте появился новый синтаксис и особенности, удовлетворяющие потребностям фронтенда, таким как:
Инструменты
На сегодняшний день в JavaScript мы привыкли к использованию различных инструментов для объединения модулей. Если мы говорим о ECMAScript модулях, вы можете использовать один из следующих:
Давайте посмотрим на упрощенной WebPack конфиг, который устанавливает точку входа и использует Babel для транспиляции JS файлов:
Конфиг состоит из основных частей:
И ваше приложение использует бандлы/транспилируемый код JS. Это общий подход для работы с бандлерами, давайте посмотрим, как заставить его работать в браузере без каких-либо бандлов.
Как сделать так, чтобы JavaScript модули работали в браузере
Поддержка Браузеров
На сегодняшний день каждый из современных браузеров имеет поддержку модулей ES6:
Где можно проверить
Как вы видели, в настоящее время можно проверить нативные JS модули в Safari Technology Preview 19+ и EDGE 15 Preview Build 14342+. Давайте скачаем и попробуем модули в действии.
ES модули доступны в Firefox
Вы можете скачать Firefox Nightly, а это означает, что скоро модули появятся в FF Developer Edition, а затем в стабильной версии браузера.
Чтобы включить ES модули:
Safari Technology Preview с доступными ES модулями
Если вы используете MacOS, достаточно просто загрузить последнюю версию Safari Technology Preview (TP) с developer.apple.com. Установите и откройте его. Начиная с Safari Technology Preview версии 21+, модули ES включены по умолчанию.
Если это Safari TP 19 или 20, убедитесь, что ES6 модули включены: откройте меню «Develop» → «Experimental Features» → «ES6 Modules».
Другой вариант — скачать последнюю Webkit Nightly и играться с ним.
EDGE 15 — включаем ES модули
Просто выберите виртуальную машину (VM) «Microsoft EDGE на Win 10 Preview (15.XXXXX)» и, например, «Virtual Box» (также бесплатно) в качестве платформы.
Установите и запустите виртуальную машину, далее откройте браузер EDGE.
Зайдите на страницу about:flags и включите флаг «Включить экспериментальные функции JavaScript» (Enable experimental JavaScript features).
Вот и все, теперь у вас есть несколько сред, где вы можете играть с нативной реализацией модулей ECMAScript.
Отличия родных и собранных модулей
Давайте начнем с нативных особенностей модулей:
Это говорит браузеру, что ваш скрипт может содержать импорт других скриптов, и они должны быть соответствующим образом обработаны. Главный вопрос, который появляется здесь:
Почему интерпретатор JavaScript не может определять модули, если файл и так по сути является модулем?
Одна из причин — нативные модули в строгом режиме по умолчанию, а классические script-ы нет:
Определение типа ожидаемой загрузки файла открывает множество способов для оптимизации (например, загрузка импортируемых файлов параллельно/до парсинга оставшейся части файла html). Вы можете найти некоторые примеры, используемые движками Microsoft Chakra JavaScript для модулей ES.
Node.js способ указать файл как модуль
Node.js окружение отличается от браузеров и использовать тег script type=«module» не особо подходит. В настоящее время все еще продолжается спор, каким подходящим способом сделать это.
Некоторые решения были отклонены сообществом:
Простой пример нативного модуля
Во-первых, давайте создадим простую демку (вы можете запустить его в браузерах, которые вы установили ранее, чтобы проверить модули). Так что это будет простой модуль, который импортирует другой и вызывает метод из него. Первый шаг — включить файл, используя:
И, наконец, импортированные утилиты:
Во-вторых, давайте проверим область видимости у модуля (демо):
В-третьих, мы проверим, что нативные модули в строгом режиме по умолчанию. Например, строгий режим запрещает удалять простые переменные. Следующее демо показывает, что появляется сообщение об ошибке в модуле:
Строгий режим нельзя обойти в нативных модулях.
Встроенный модуль в тег script
Как и обычные скрипты, вы можете встраивать код, вместо того, чтобы разделять их по отдельным файлам. В предыдущем демо вы можете просто вставить main.js непосредственно в тег script type=«module» что приведет к такому же поведению:
Как браузер загружает и выполняет модули
Нативные модули (асинхронные) по умолчанию имеют поведение deffered скриптов. Чтобы понять это, мы можем представить каждый тег script type=«module» с атрибутом defer и без. Вот изображение из спецификации, которое объясняет поведение:
Это означает, что по умолчанию скрипты в модулях не блокируют, загружаются параллельно и выполняются, когда страница завершает парсинг html. Вы можете изменить это поведение, добавив атрибут async, тогда скрипт будет выполнен, как только он загрузится.
Главное отличие нативных модулей от обычных скриптов заключается в том, что обычные скрипты загружаются и выполняются сразу же, блокируя парсинг html. Чтобы представить это, посмотрите демо с разными вариантами атрибутов в теге script, где первым будет выполнен обычный скрипт без атрибутов defer \ async:
Порядок загрузки зависит от реализации браузеров, размера скриптов, количества импортируемых скриптов и т. д.
Все вышесказанное дается для первого знакомства с нативными ECMAScript модулями. В следующей статье будут разобраны способы взаимодействия модулей, определение поддержки в браузерах, конкретные моменты и различия с обычными бандлами и т. д.
Если хотите узнать больше сейчас, предлагаю пройтись по ссылкам:
Нативные EcmaScript модули: новые возможности и отличия от webpack
В предыдущей статье Нативные ECMAScript модули — первый обзор я рассказал историю JavaScript модулей и текущее состояние дел реализации нативных EcmaScript модулей.
Сейчас доступны две реализации, которые мы попробуем сравнить с бандлерами модулей.
Вы можете найти больше примеров, прочитав часть спецификации HTML resolve a module specifier. Вот примеры валидных спецификаторов оттуда:
Итого про путь модуля:
Раз зашла речь про абсолютные URL, давайте проверим, как мы сможем их использовать.
Абсолютные URL и CORS (Cross-Origin Resource Sharing)
Еще одно отличие от бандлов — это возможность загружать файлы с других доменов (например, загрузка модулей с CDN).
Давайте создадим демо, где мы загрузим модуль main-bundled.js, который в свою очередь имортирует и использует blog.hospodarets.com/…/utils.js c другого домена.
Демо будет работать точно так же, как если вы загрузили скрипты со своего домена. Хорошо, что есть поддержка абсолютных URL и работает она точно так же, как у классических скриптов, которые могут быть загружены из любого источника.
Конечно, такие запросы следуют CORS правилам. Например, в предыдущем примере мы загружали скрипт из https://blog.hospodarets.com/demos/native-javascript-modules/js/utils.js, что позволяло делать CORS запросы. Это можно легко определить, посмотрев в заголовки ответа:
Мы можем видеть access-control-allow-origin: * заголовок.
Этот заголовок Access-Control-Allow-Origin: | * определяет URI, который может получить доступ к ресурсу. Специальный символ * позволяет любому запросу получить доступ к ресурсу, поэтому наше демо работает.
Но давайте поменяем main-bundled.js, будем загружать utils.js из другого места (демо)
И демо перестает работать. Несмотря на это, вы можете открыть
hospodarets.com/…/native-javascript-modules/js/utils.js
в вашем браузере и убедиться, что его содержание совпадает с
blog.hospodarets.com/…/utils.js.
Отличие заключается в том, что второй utils.js не дает доступ к ресурсу на уровне заголовка access-control-allow-origin :
который интерпретируется браузером как отказ от любого другого источника (https://plnkr.co в нашем случае) для доступа к ресурсу, поэтому демо перестает работать со следующей ошибкой:
Есть некоторые другие ограничения, которые применяются к нативным модулям, классическим скриптам и ресурсам. Например, вы не сможете импортировать HTTP модуль в ваш HTTPS сайт (Mixed Content, демо)
Итого:
Атрибуты script
Итого:
Как определить, что скрипт загружается или не может быть выполнен из-за ошибки
Как только я начал использовать ES модули, главный вопрос, который у меня возник, — как определить, что скрипт был загружен или произошла ошибка?
Мы уже знаем, что нативные модули ведут себя как deferred скрипты по умолчанию. С другой стороны, они могут прекратить выполнение, если, например, граф скрипта не может быть выполнен/загружен.
Для этих двух случаев мы должны каким-то образом детектировать факт того, что скрипт не загрузился либо произошла ошибка.
Давайте попробуем использовать классический способ подключения скриптов, изменив немного код. Создадим метод, который будет принимать параметры и выполнять скрипт с ними:
Метод возвращает Promise, который позволяет определить, был ли загружен скрипт или была ошибка при загрузке:
А вот демо, где успешно выполняется скрипт. В данном примере скрипт выполнится и наш success callback будет выполнен. Теперь сделаем так, чтобы в модуле была ошибка (демо):
В этом случае у нас возникает ошибка, которую видно в консоле:
Поэтому наш reject callback выполнится. Вы также увидите сообщение об ошибке, если вы пытаетесь использовать import \ export в других модулях (демо):
Теперь у нас есть возможность подключать скрипты и быть уверенными, что скрипты могут/не могут загрузиться.
Итого:
Особенности нативных модулей
Нативные модули — singleton
Согласно спецификации, неважно, сколько раз вы будете импортировать один и тот же модуль. Все модули представляют собой синглтон. Пример:
Вы можете импортировать этот модуль столько раз, сколько вы хотите. Он будет выполнен только один раз, window.counter и экспортируемый counter будет равняться 1 (демо)
Импорты “всплывают”
Как и функции в JavaScript, imports “поднимаются” (hoisted). О таком поведении важно знать. Вы можете применять к написанию импортов те же правила, что и к объявлению переменных — писать их всегда в начале файла. Вот почему следующий код работает:
Порядок выполнения кода ниже (демо):
Импорты и экспорты не могут быть вложены в блоки
В связи с тем, что структура ES модулей статическая, они не могут быть импортированы/экспортированы внутри условных блоков. Это широко используется для оптимизации загрузки кода. Вы также не можете обернуть их в блок try<>catch()<> или что-то подобное.
Итого:
Как определить, что есть поддержка модулей
Браузеры начали добавлять ES модули, и нам нужен способ, чтобы обнаружить, что браузер их поддерживает. Первые мысли о том, как можно определить поддержку модулей:
Данный вариант не работает, так как импорт/экспорт предназначены для использования только для функциональных модулей. Эти примеры выполняются с ошибкой “Syntax errors”. Еще хуже, что импорт/экспорт не должен загружаться как классический скрипт. Поэтому нам нужен другой способ.
Определение поддержки ES модулей в браузерах
Вряд ли вам захочется создавать отдельный скрипт в проекте для такой проверки. Для этого у нас есть есть Blob() API, чтобы создать пустой скрипт и обеспечить правильный MIME тип для него. Для того чтобы получить URL представление скрипта, который мы можем присвоить атрибуту src, нужно воспользоваться методом URL.createObjectURL()
И, наконец, после нашего успешного Promise-а мы должны немного прибраться: удалить скрипт из DOM и удалить ненужные URL объекты из памяти.
А теперь все это объединим в примере:
Как определить, что скрипт выполнился как нативный модуль
Круто, теперь мы можем понять, поддерживает ли браузер нативные модули. Но что если мы хотим знать, в каком режиме выполняется загружаемый скрипт?
В объекте документа есть такое свойство document.currentScript, которое содержит ссылку на текущий скрипт. Поэтому можно проверить атрибут type :
но currentScript не поддерживается в модулях (демо).
Мы можем уточнить, является скрипт модулем через проверку ссылки на контекст (проще говоря, зысь). Если this ссылается на глобальный объект, то будет понятно, что скрипт не нативный модуль.
Но надо учитывать, что этот метод может дать ложные данные, например, bound.
Переход с Webpack на нативные ES модули
Пора переписать некоторые Webpack модули на нативные, сравнить синтаксис и убедиться, что всё по-прежнему работает. Давайте возьмем простой пример, который использует популярную библиотеку lodash.
Webpack найдет node_modules/lodash/map.js и заимпортирует файл. Удобно и быстро, согласны? Давайте попробуем следующий пример:
Прежде всего, lodash просто не работает с ES модулями. Если вы посмотрите на исходный код, вы увидите, что использован commonjs подход:
После небольших поисков выяснилось, что авторы lodash создали специальный проект для этого — lodash-es — который содержит библиотечные модули lodash в виде ES модулей.
Если мы проверим код, мы увидим, что это ES модули:
Вот обычная структура нашего приложения (которое мы будем портировать):
Мы уже знаем, что мы не можем не писать расширение файла у нативных модулей, поэтому в первую очередь мы должны добавить их.
Во-вторых, URL-ы у нативных модулей должны быть абсолютными или должны начинаться с “/”, “./”, или “../”. Ох, это самое сложное. Для нашей структуры мы должны сделать следующее:
А через некоторое время мы можем начать с более сложной структуры организации модулей. У нас может быть много относительных и очень длинных url-ов, поэтому вы можете легко заменить все файлы на следующий вариант:
Обычно корень директории указывает на местоположение index.html, поэтому тег не влияет на поведение импортируемых модулей.
В конце этой главы отмечу, что для импорта скриптов, модулей и зависимостей браузер делает запросы (как и для других ресурсов). В нашем случае браузер загружает все lodash зависимости, в результате чего около 600 файлов попадают в браузер:
Как вы можете догадаться, это очень плохая идея грузить так много файлов, особенно если у вас нет поддержки протокола HTTP/2 на сайте.
Теперь вы знаете, что можно перейти с Webpack-а на нативные модули и даже знаете о существовании lodash-es.
Итого:
Использование ES modules с fallback-ом
Давайте используем все наши знания, чтобы создать полезный скрипт и применить его, например, в нашем lodash демо.
Мы будем проверять, если браузер поддерживает ES модули (используя checkJsModulesSupport()) и, в зависимости от этого, решать что подключать пользователю. Если модули поддерживаются, мы будем загружать файл main-native.js для них. В противном случае, мы будем подключать Webpack-ом собранный JS файл (используя insertJS()).
Чтобы пример работал для всех браузеров, давайте предоставим API, с помощью которого можно проставить скриптам атрибуты, которые будут указывать, каким способом мы хотим их загрузить.
И вот код, который заставит все это работать, используя предыдущие примеры, обсуждаемые ранее:
В настоящее время идет обсуждение возможности добавить нативные атрибуты nomodule или nosupport к скрипту, который будет обеспечивать лучшую совместимость для fallback-а (спасибо @rauschma, предложившему это).
Заключение
Мы посмотрели на практике различие между ES модулями и классическими скриптами. Узнали, как определить, если модуль загрузился или произошла ошибка. Теперь мы знаем, как использовать ES модули со сторонними библиотеками.
Кроме того, у нас есть полезный скрипт es-modules-utils на Github, который может обеспечить обратную совместимость для браузеров, которые не поддерживают ES модули.
P. S. Вы также можете прочитать мою статью о возможности динамической загрузки скриптов, использующих динамический оператор import(): Native ECMAScript modules: dynamic import().



