メインコンテンツまでスキップ

JavaScriptモジュール

Kotlinプロジェクトは、さまざまな一般的なモジュールシステムに対応したJavaScriptモジュールにコンパイルできます。現在、JavaScriptモジュールに対して以下の構成をサポートしています。

  • [AMDCommonJSの両方に対応するUnified Module Definitions (UMD)。 UMDモジュールは、インポートなしで、またはモジュールシステムが存在しない場合でも実行できます。これは、browserおよびnodejsターゲットのデフォルトオプションです。
  • 特にRequireJSライブラリで使用されるAsynchronous Module Definitions (AMD)
  • Node.js/npmで広く使用されているCommonJS (require関数とmodule.exportsオブジェクト)。
  • プレーン。モジュールシステム用にコンパイルしません。グローバルスコープでモジュール名を使用してアクセスできます。

ブラウザターゲット

Webブラウザ環境でコードを実行し、UMD以外のモジュールシステムを使用する場合は、webpackTask構成ブロックで目的のモジュールタイプを指定できます。たとえば、CommonJSに切り替えるには、次のようにします。

kotlin {
js {
browser {
webpackTask {
output.libraryTarget = "commonjs2"
}
}
binaries.executable()
}
}

Webpackは、CommonJSの2つの異なる種類、commonjscommonjs2を提供します。これらは宣言の利用方法に影響を与えます。ほとんどの場合、生成されたライブラリにmodule.exports構文を追加するcommonjs2を使用することをお勧めします。または、CommonJS仕様に厳密に準拠するcommonjsオプションを選択することもできます。commonjscommonjs2の違いについて詳しくは、Webpackリポジトリを参照してください。

JavaScriptライブラリとNode.jsファイル

JavaScriptまたはNode.js環境で使用するためのライブラリを作成し、別のモジュールシステムを使用する場合は、手順が少し異なります。

ターゲットモジュールシステムの選択

ターゲットモジュールシステムを選択するには、GradleビルドスクリプトでmoduleKindコンパイラオプションを設定します。

tasks.withType<org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrLink> {
compilerOptions.moduleKind.set(org.jetbrains.kotlin.gradle.dsl.JsModuleKind.MODULE_COMMONJS)
}

使用可能な値は、umd(デフォルト)、commonjsamdplainです。

注記

これは、webpackTask.output.libraryTargetの調整とは異なります。ライブラリターゲットは、(コードがすでにコンパイルされた後)_webpackによって生成される_出力を変更します。compilerOptions.moduleKindは、_Kotlinコンパイラによって_生成される出力を変更します。

Kotlin Gradle DSLには、CommonJSモジュール種類を設定するためのショートカットもあります。

kotlin {
js {
useCommonJs()
// ...
}
}

@JsModule アノテーション

externalなクラス、パッケージ、関数、またはプロパティがJavaScriptモジュールであることをKotlinに伝えるには、@JsModuleアノテーションを使用できます。 "hello"というCommonJSモジュールがあるとします。

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アノテーションでマークされたファイルは、非externalメンバーを宣言できません。 次の例は、コンパイル時エラーを生成します。

@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にインポートするには、2つの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としてマークされている場合、JavaScriptモジュールにコンパイルしない場合、Kotlinコードからそれを使用できません。 通常、開発者はJavaScriptモジュールとダウンロード可能な.jsファイルの両方としてライブラリを配布します。これらのファイルは、プロジェクトの静的リソースにコピーして、<script>タグを介して含めることができます。 @JsModule宣言を非モジュール環境から使用しても問題ないことをKotlinに伝えるには、@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のほとんどのユースケースでは、NPMでkotlinパッケージとして入手可能なkotlin-stdlib-jsへのGradle依存関係を使用することをお勧めします。