23
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

KotlinAdvent Calendar 2020

Day 18

Kotlin/JSでWebフロント開発をはじめよう

Last updated at Posted at 2020-12-18

こんにちは、マヤミトです。
この記事はKotlin Advent Calendar 2020 18日目の記事です。
皆さんはKotlin/JSを使っていますか?まだまだ記事が少ないこともあり、どう始めればいいのかわからないという人もいるかもしれません。今回は、普段Kotlinを書いている人がKotlin/JSでWebフロント開発を始めるのに最低限必要な知識を身につけられることをゴールにこの記事を書いています。解説不足の部分があれば気軽にコメントしてください。

Kotlin/JSについて

Kotlin/JSは、文字通りKotlinをJavaScriptにトランスパイルする技術です。
https://kotlinlang.org/docs/reference/js-overview.html
当然JVMの資産は使えませんが、その代わりにDOMの操作などをKotlinでType Safeに扱うことができます。
NodeJSの資産を使ってサーバーサイドの開発もできますが、今回の記事では特に触れないことにします(興味のある方は以前書いたこちらの記事をご覧ください)。

Kotlin/JSを扱う方法は大きく分けて2種類あり、通常のWebフロント開発のようにnpmのプロジェクトとして作成する方法と、通常のKotlinでの開発のようにGradleのプロジェクトとして作成する方法があります。古い記事ではnpmを使う方法が多くヒットしますが、最近だとGradle Pluginを使う後者の方法が公式では推奨されており、今回はそちらの方法を解説します。

今回使用したバージョンなど

IntelliJ IDEA Ultimate 2020.3
Kotlin 1.4.21
Gradle 6.7

Kotlin/JSは情報が古くなるサイクルが早いので、この記事の通りにやっても動かない場合は最新の情報を公式ドキュメントなどに直接探しに行くことをオススメします(まあその公式ドキュメントもたまに古かったりしますが……)

簡単なプロジェクトを作ってみる

プロジェクトのセットアップ

IntelliJ IDEAの New ProjectGradle から Kotlin/JS for browser を選択し、新規プロジェクトを作成します。
この際、 Kotlin DSL build script にチェックを付けることをおすすめします。
スクリーンショット 2020-12-18 18.05.29.png

このようなプロジェクトが生成されると思います。
スクリーンショット 2020-12-18 19.19.29.png

main.kt
import kotlinx.browser.document

fun main() {
    document.write("Hello, world!")
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HelloKotlinJS</title>
    <script src="HelloKotlinJS.js"></script>
</head>
<body>

</body>
</html>
build.gradle.kts
plugins {
    id("org.jetbrains.kotlin.js") version "1.4.21"
}

group = "com.yt8492"
version = "1.0.0"

repositories {
    mavenCentral()
}

dependencies {
    implementation(kotlin("stdlib-js"))
}

kotlin {
    js {
        browser {
            webpackTask {
                cssSupport.enabled = true
            }

            runTask {
                cssSupport.enabled = true
            }

            testTask {
                useKarma {
                    useChromeHeadless()
                    webpackConfig.cssSupport.enabled = true
                }
            }
        }
        binaries.executable()
    }
}

ページに Hello, world! と表示されるだけの簡単なコードです。
デフォルトでは、 プロジェクト名.js をHTMLから読み込んでいます。これが実際にビルドして吐き出されるファイル名です。任意のファイル名に設定したい場合、 build.gradle.kts に設定を追記します。

build.gradle.kts
kotlin {
    js {
        browser {
            webpackTask {
                cssSupport.enabled = true
                outputFileName = "main.js" // 追加
            }

            runTask {
                cssSupport.enabled = true
                outputFileName = "main.js" // 追加
            }

            testTask {
                useKarma {
                    useChromeHeadless()
                    webpackConfig.cssSupport.enabled = true
                    webpackConfig.outputFileName = "main.js" // 追加
                }
            }
        }
        binaries.executable()
    }
}

実行してみる

プロジェクトルートで以下を実行します。

./gradlew browserRun --continuous

するとブラウザが立ち上がり、実際にページが表示されると思います。

スクリーンショット 2020-12-18 19.20.59.png

--continuous オプションはホットリロードを有効にします。開発中はこのオプションをつけて実行すると便利です。

ビルドしてみる

プロジェクトルートで以下を実行します。

./gradlew browserWebpack

プロジェクトルート/build/distributions/ 以下にトランスパイルされたJavaScriptのファイルと resources 以下のファイルが吐き出されるので、 index.html をブラウザで開くと、先程と同じページが表示されると思います。

DOMの操作をしてみる

デフォルトでは単純に Hello, world! と表示するだけでしたが、ボタンをクリックしたらテキストが表示されるようなコードを書いてみましょう。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Hello Kotlin/JS</title>
</head>
<body>
<button id="greetButton">Greet</button>
<h1 id="greetText"></h1>
</body>
<script src="main.js"></script>
</html>
main.kt
import kotlinx.browser.document
import org.w3c.dom.HTMLButtonElement
import org.w3c.dom.HTMLHeadingElement

fun main() {
    val greetButton = document.getElementById("greetButton") as HTMLButtonElement
    val greetText = document.getElementById("greetText") as HTMLHeadingElement
    greetButton.addEventListener("click", {
        greetText.textContent = "Hello, Kotlin/JS!"
    })
}

Greet ボタンを押すと、以下のように Hello, Kotlin/JS! と表示されると思います。
スクリーンショット 2020-12-18 22.42.49.png

document.getElementById で要素を取得して操作しているのがわかると思います。

Kotlin/JSで使えるライブラリ集

今回の記事の目的はKotlin/JSでの開発に最低限必要な知識を身に着けてもらうことなので、各種ライブラリの使い方はここでは解説しませんが、自分がよく使うライブラリを紹介したいと思います。

kotlin-react

文字通り、KotlinでReactを扱うことができるようになるラッパーライブラリです。Kotlin/JS向けのJavaScriptラッパーライブラリ集kotlin-wrappersのうちの一つです。
https://github.com/JetBrains/kotlin-wrappers/blob/master/kotlin-react/README.md
最新版ではReact v17に対応していて、hooksも普通に使えます。
kotlin-wrappersリポジトリには、React Routerのラッパーやstyled-componentsのラッパーなどもあります。それらと組み合わせて使うと良いでしょう。

Ktor Client

Kotlin/MPP対応のHTTP Clientライブラリです。当然Kotlin/JSでも使うことができます。
https://ktor.io/docs/clients-index.html

Klock

Kotlin/MPP対応の時間を扱うライブラリです。Kotlin/JVMではJavaのDate型などが使えましたが、当然Kotlin/JSでは使えないので、こういったライブラリを使うと良いでしょう。
https://korlibs.soywiz.com/klock/

終わりに

今回はKotlin/JS初心者向けの記事でした。Kotlin好きな皆さんがこの記事を読んでKotlin/JSを始めてくれると嬉しいです。
最近のKotlin界隈ではKMMが盛り上がりを見せていますが、Kotlin/JSも流行るといいなぁ……と思いながら地道に活動をしています。興味のある方はぜひ一度試してみてほしいです。

23
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?