Поддержка ECMAScript 6 в JAICP
Бета
До осени 2022 года в JAICP поддерживался только один диалект JavaScript (далее JS), а именно его реализация согласно спецификации ECMAScript 5 (ES5) на движке Nashorn. Она была предложена в 2009 году и успела значительно устареть, поэтому возможности написания JS-кода в JAICP не в полной мере отражают современные профессиональные стандарты.
-
Разработчики на JAICP не могут либо могут лишь ограниченно использовать востребованные возможности современных версий JS. В свою очередь, новые пользователи с опытом разработки не могут в полной мере применить свои навыки.
-
Среда исполнения JS в JAICP изолирована от экосистемы пакетов, сформированной сообществом JS-разработчиков, и не позволяет подключать к проектам внешние зависимости, кроме встроенных в платформу (Underscore.js и Moment.js).
Сейчас в JAICP доступна новая среда исполнения JS, которая решает обе эти проблемы и открывает возможность разрабатывать проекты на современном диалекте JS (далее ES6) с поддержкой внешних зависимостей.
Тег scriptEs6
В JAICP DSL доступен тег реакции scriptEs6
.
Тег работает аналогично script
с той разницей, что при попадании в стейт код внутри тега запускается в новой среде исполнения.
Это позволяет использовать в нем возможности ES6, недоступные внутри обычного тега script
:
state: HeadsOrTails
q!: * {орел * решка} *
scriptEs6:
const bit = $reactions.random(2); // Объявление переменной через const
$reactions.answer(`Результат: ${bit ? "орел" : "решка"}.`); // Формирование строки по шаблону
Для запуска кода используется платформа Node.js версии 20.
Это означает, что внутри него доступны возможности спецификаций вплоть до ECMAScript 2023,
в том числе разбиение кода на модули, новые структуры данных (множества Set
, отображения Map
), классы, асинхронные функции и многое другое.
Есть и другие теги JAICP DSL, внутри которых пишется JS-код: if
, elseif
, init
.
Пока что эти теги не имеют аналогов, в которых можно использовать ES6.
Подключение зависимостей
Как и раньше, сложную бизнес-логику рекомендуется не описывать напрямую внутри тега scriptEs6
, а выносить ее в отдельные JS-файлы,
которые затем подключаются к сценарию при помощи тега require
.
Однако есть важные отличия между тем, как используются именованные объекты (переменные, функции, классы) из файлов,
написанных на ES5 и ES6.
Зависимости на ES5
Если код зависимости написан на ES5 и запускается в старой среде исполнения,
то JS-файл нужно обязательно импортироват ь в сценарий при помощи тега require
без параметров.
При этом если на верхнем уровне вложенности этого файла объявлены переменные или функции,
то они автоматически помещаются в глобальную область видимости.
К ним можно обратиться из любого тега script
, scriptEs6
, а также из любого другого подключенного JS-файла.
- main.sc
- dialog.js
- defaults.js
require: dialog.js
require: defaults.js
theme: /
state: Hello
q!: * привет *
script:
sayHello();
function sayHello() {
// Предположим, что имя пользователя содержится в $client.name
var name = $jsapi.context().client.name;
// Переменная DEFAULT_CLIENT_NAME задана в defaults.js, и к ней можно обратиться
$reactions.answer("Привет, " + (name || DEFAULT_CLIENT_NAME) + "!");
}
var DEFAULT_CLIENT_NAME = "таинственный незнакомец";