Kotlin/JS は Kotlin/JS としてセットアップするか、 Kotlin MultiPlatform Project(Kotlin MPP) としてセットアップするかの二種類があります。
ここでは全体としての Kotlin/JS と、Kotlin/MPP と対になっている Kotlin/JS の表記が混じっています。
基本構成
Kotlinファイルは src/jsMain/kotlin 以下に記述します。 build.gradle.kts でセットアップしました。 1.4-M1 を使用しましたが、 1.3.71 でも大丈夫でした。
Kotlin/MPP
plugins {
id("org.jetbrains.kotlin.multiplatform") version ("1.4-M1")
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
maven { url = uri("https://dl.bintray.com/kotlin/kotlin-eap") }
mavenCentral()
}
kotlin {
js()
sourceSets {
getByName("jsMain") {
dependencies {
implementation(kotlin("stdlib-js"))
implementation(npm("firebase-admin", "^8.10.0"))
implementation(npm("firebase-functions", "^3.6.1"))
}
}
}
}
Kotlin/JS
plugins {
id("org.jetbrains.kotlin.js") version ("1.4-M1")
}
group = "org.example"
version = "1.0-SNAPSHOT"
repositories {
maven { url = uri("https://dl.bintray.com/kotlin/kotlin-eap") }
mavenCentral()
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-js")
implementation(npm("firebase-admin", "^8.10.0"))
implementation(npm("firebase-functions", "^3.6.1"))
}
dependencies
package.json の dependencies は、gradleの dependencies に書けば大丈夫です。
implementation(npm("firebase-admin", "^8.10.0")) implementation(npm("firebase-functions", "^3.6.1"))
"dependencies": { "kotlin": "1.4.0-M1", "firebase-admin": "^8.10.0", "firebase-functions": "^3.6.1" },
devDependencies, peerDependencies, optionalDependencies, bundledDependencies, workspaces
packageJson で org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson を操作します。この PackageJson を Gson でそのまま出力することで package.json が出力されます。
Kotlin/MPP
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.MAIN_COMPILATION_NAME kotlin { js { nodejs { compilations.getByName(MAIN_COMPILATION_NAME) { packageJson { devDependencies["eslint"] = "^5.12.0" } } } } }
Kotlin/JS
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.MAIN_COMPILATION_NAME kotlin { target { compilations { getByName(KotlinCompilation.MAIN_COMPILATION_NAME) { packageJson { devDependencies["eslint"] = "^5.12.0" } } } } }
その他のpackage.jsonの要素
PackageJson を Gson でそのまま出力しているので、ここに定義されていなければ package.json の出力を変えることはできません。
なので以下のように新しく定義して、 package.json が出力された後に読み込んで出力し直します。
kotlin/JSは JsJar ですが、Kotlin/MPPは jsJar なので注意が必要です。
共通
import org.jetbrains.kotlin.gradle.targets.js.npm.PackageJson val PROJECT_NAME = rootProject.name kotlin { tasks.first { it.name.toUpperCase() == "JSJAR" } .doLast { customizePackageJson() } } fun customizePackageJson() { val packageJsonFile = File("build/js/packages/$PROJECT_NAME/package.json") val packageJson = Gson().fromJson(packageJsonFile.readText(), PackageJson::class.java) val customPackageJson = CustomPackageJson(packageJson) { engines["node"] = "10" scripts["lint"] = "" scripts["serve"] = "firebase emulators:start --only functions" scripts["shell"] = "firebase functions:shell" scripts["start"] = "npm run shell" scripts["deploy"] = "firebase deploy --only functions" scripts["logs"] = "firebase functions:log" } packageJsonFile.writeText( com.google.gson.GsonBuilder() .setPrettyPrinting() .create() .toJson(customPackageJson) ) } @Suppress("USELESS_ELVIS") class CustomPackageJson(packageJson: PackageJson, block: CustomPackageJson.() -> Unit) { var private: Boolean? = packageJson.private var main: String? = packageJson.main var workspaces: Collection<String>? = packageJson.workspaces val devDependencies = packageJson.devDependencies get() = field ?: mutableMapOf() val dependencies = packageJson.dependencies get() = field ?: mutableMapOf() val peerDependencies = packageJson.peerDependencies get() = field ?: mutableMapOf() val optionalDependencies = packageJson.optionalDependencies get() = field ?: mutableMapOf() val bundledDependencies = packageJson.bundledDependencies get() = field ?: mutableListOf() val engines = mutableMapOf<String, String>() get() = field ?: mutableMapOf() val scripts = mutableMapOf<String, String>() get() = field ?: mutableMapOf() init { block(this) } }
おわりに
Kotlin/JSに関する情報が全然ないのと、コードジャンプが使えなくてコードを追うのが大変でした。
それから、Kotlin/MPP では使用できるのに、 Kotlin/JS では java.nio が使えなかったりする違いがあってGradleスクリプトが書きにくいとかあるので Kotlin/MPP で書くことをおすすめします。