Модули JavaScript
Вы можете скомпилировать свои проекты Kotlin в модули JavaScript для различных популярных систем модулей. В настоящее время мы поддерживаем следующие конфигурации для модулей JavaScript:
Единые определения модулей (UMD), которые совместимы как с AMD, так и с CommonJS. Модули UMD также могут быть выполнены без импорта или при отсутствии системы модулей. Это параметр по умолчанию для
browserиnodejsцелей.Асинхронные определения модулей (AMD), которые используются в частности библиотекой RequireJS.
CommonJS, широко используемый Node.js/npm (
requireфункция иmodule.exportsобъект)Простой. Не компилировать для никакой системы модулей. Вы можете получить доступ к модулю по его имени в глобальной области видимости.
Цели браузера
Если вы ориентируетесь на браузер и хотите использовать систему модулей, отличную от UMD, вы можете указать желаемый тип модуля в блоке конфигурации webpackTask. Например, чтобы переключиться на CommonJS, используйте:
kotlin {
js {
browser {
webpackTask {
output.libraryTarget = "commonjs2"
}
}
binaries.executable()
}
}
Webpack предоставляет два разных «варианта» CommonJS, commonjs и commonjs2, которые влияют на способ, которым ваши объявления становятся доступными. Хотя в большинстве случаев вы, вероятно, захотите commonjs2, который добавляет синтаксис module.exports к сгенерированной библиотеке, вы также можете выбрать вариант «чистый» commonjs, который точно реализует спецификацию CommonJS. Чтобы узнать больше о различиях между commonjs и commonjs2, обратитесь сюда.
Библиотеки JavaScript и файлы Node.js
Если вы создаёте библиотеку, которая будет использоваться из JavaScript или файла Node.js, и хотите использовать другую систему модулей, инструкции немного отличаются.
Выбор целевой системы модулей
Чтобы выбрать тип модуля, установите параметр компилятора moduleKind в скрипте сборки Gradle.
tasks.named<KotlinJsCompile>("compileKotlinJs").configure {
kotlinOptions.moduleKind = "commonjs"
}
compileKotlinJs.kotlinOptions.moduleKind = "commonjs"
Доступные значения: umd (по умолчанию), commonjs, amd, plain.
В Kotlin Gradle DSL также есть сокращение для установки типа модуля CommonJS:
kotlin {
js {
useCommonJs()
// . . .
}
}
Аннотация @JsModule
Чтобы сообщить Kotlin, что external класс, пакет, функция или свойство является модулем JavaScript, вы можете использовать аннотацию @JsModule. Представьте, что у вас есть следующий модуль CommonJS под названием «hello»:
module.exports.sayHello = function(name) { alert("Hello, " + name); }
Вы должны объявить его следующим образом в Kotlin:
@JsModule("hello")
external fun sayHello(name: String)
Применение @JsModule к пакетам
Некоторые библиотеки JavaScript экспортируют пакеты (пространства имён) вместо функций и классов. С точки зрения JavaScript, это объект, имеющий члены, которые являются классами, функциями и свойствами. Импорт этих пакетов как объектов Kotlin часто выглядит неестественно. Компилятор может сопоставить импортированные JavaScript-пакеты с Kotlin-пакетами, используя следующую запись:
@file:JsModule("extModule")
package ext.jspackage.name
external fun foo()
external class C
где соответствующий модуль JavaScript объявлен так:
module.exports = {
foo: { /* some code here */ },
C: { /* some code here */ }
}
Файлы, помеченные аннотацией @file:JsModule, не могут объявлять члены, отличные от внешних. Приведённый ниже пример выведет ошибку времени компиляции:
@file:JsModule("extModule")
package ext.jspackage.name
external fun foo()
fun bar() = "!" + foo() + "!" // error here
Импорт более глубоких иерархий пакетов
В предыдущем примере модуль JavaScript экспортирует один пакет. Однако некоторые библиотеки JavaScript экспортируют несколько пакетов изнутри модуля. Этот случай также поддерживается Kotlin, хотя вам нужно объявить новый .kt файл для каждого импортируемого вами пакета.
Например, давайте усложним пример:
module.exports = {
mylib: {
pkg1: {
foo: function() { /* some code here */ },
bar: function() { /* some code here */ }
},
pkg2: {
baz: function() { /* some code here */ }
}
}
}
Для импорта этого модуля в Kotlin вам нужно написать два Kotlin-исходных файла:
@file:JsModule("extModule")
@file:JsQualifier("mylib.pkg1")
package extlib.pkg1
external fun foo()
external fun bar()
и
@file:JsModule("extModule")
@file:JsQualifier("mylib.pkg2")
package extlib.pkg2
external fun baz()
Аннотация @JsNonModule
Когда объявление помечается как @JsModule, вы не можете использовать его из кода Kotlin, когда не компилируете его в модуль JavaScript. Обычно разработчики распространяют свои библиотеки как модули JavaScript и загружаемые .js файлы, которые можно скопировать в статические ресурсы вашего проекта и включить с помощью тега <script>. Чтобы сообщить Kotlin, что использование @JsModule объявления из среды, не являющейся модулем, допустимо, добавьте аннотацию @JsNonModule. Например, рассмотрим следующий код JavaScript:
function topLevelSayHello(name) { alert("Hello, " + name); }
if (module && module.exports) {
module.exports = topLevelSayHello;
}
Вы можете описать его в Kotlin следующим образом:
@JsModule("hello")
@JsNonModule
@JsName("topLevelSayHello")
external fun sayHello(name: String)
Система модулей, используемая стандартной библиотекой Kotlin
Kotlin поставляется со стандартной библиотекой Kotlin/JS как единственным файлом, который сам скомпилирован как модуль UMD, поэтому вы можете использовать его с любой системой модулей, описанной выше. Хотя для большинства случаев использования Kotlin/JS рекомендуется использовать зависимость Gradle от kotlin-stdlib-js, она также доступна в NPM как пакет kotlin.
© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/js-modules.html