Модули 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