Kotlin/JSでサイトを作って公開する
投稿日 : | 0 日前
文字数(だいたい) : 6625
夜勤明け (のなんでも出来そうな気分の中) Kotlin/JSを初めて触ったら面白かったので記事にする。
本題
残りの日数を数えるWebサイトをKotlin/JSで作ります。
これなら簡単に作れそう。
Kotlin/JS #とは
KotlinコードをJSにトランスパイルする。
JSみたいにDOM操作とかも出来る。
IDEAを開き新規プロジェクトを作成します
Gradleを押して、Kotlin DSL build scriptにチェックを入れ、Kotlin/JS for browserを選択します。

名前とかは適当に入れてください。

生成後しばらく待ちます。
起動する
IDEA右下のTerminalをおして、以下のコマンドを入れます。
./gradlew run --continuous
これはホットリロード付きで開発サーバーを起動するコマンドです。勝手にブラウザが起動するはずです。
初回起動時は、ファイアウォールが許可するか聞いてくるので許可してあげてください。
無事ブラウザにHello Worldが出てれば成功です。

index.html を書き換える
src/main/resources/index.htmlがindex.htmlになります。
scriptタグを移動
<script>タグを<body>タグの下に移動させます。
これをしないと多分DOM操作時にぬるぽ吐きます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CountdownKotlinJS</title>
</head>
<body>
</body>
<script src="CountdownKotlinJS.js"></script>
</html>
適当にUIを作る
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>CountdownKotlinJS</title>
</head>
<style>
.title {
font-size: 30px;
}
.subtitle {
font-size: 20px;
}
.card {
width: 50%;
margin-left: auto;
margin-right: auto;
margin-bottom: 10px;
border-radius: 5px;
padding: 10px;
box-shadow: 0 2px 5px #ccc;
}
.divider {
border-top: 1px solid #ccc
}
</style>
<body>
<div class="card">
<p class="title">カウントダウン</p>
<div class="divider"></div>
<p class="subtitle">日付の選択</p>
<p align="center">
<input type="date" id="date_input">
<input type="button" id="calc_button" value="残り日数計算">
</p>
<div class="divider"></div>
<p class="subtitle">残り</p>
<p align="center" class="title" id="countdown_text"></p>
</div>
</body>
<script src="CountdownKotlinJS.js"></script>
</html>
Kotlin
とりあえず日付を取得するまで
import kotlinx.browser.document
import kotlinx.browser.window
import org.w3c.dom.HTMLInputElement
fun main() {
// 残り日数表示要素
val countdownTextElement = document.getElementById("countdown_text")!!
// ボタン
val calcButton = document.getElementById("calc_button")!!
// 日付入力要素
val dateInputElement = document.getElementById("date_input")!! as HTMLInputElement
// ボタン押したとき
calcButton.addEventListener("click", {
// 日付取得
val dateString = dateInputElement.value
window.alert(dateString)
})
}
日付を入れてボタンを押したらアラートが出ると思います。

日付計算ライブラリ
別にJS標準のDateを使うって手もある。
今回はdayjsを入れようと思います。
Kotlin/JSでもnpmからライブラリを入れることが出来ます。
build.gradle.ktsに書き足します。
日付ライブラリといえばmoment.jsですが、今回はdayjsを使います。軽いらしい?
plugins {
id("org.jetbrains.kotlin.js") version "1.5.10"
}
group = "io.github.takusan23"
version = "1.0.0"
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib-js"))
// 日付計算
implementation(npm("dayjs", "1.10.6"))
}
JSのライブラリをKotlinで使う
JSは動的に型をつけますが、Kotlinでは静的に型をつけます。
普通に考えるとJSライブラリが使えないように見えますが、Kotlin/JSにはdynamic型が用意されています。
これを使うとJSみたいに書くことが出来ます。なおこれを使うとKotlinのNull安全等の恩恵が受けれなくなるのでKotlinで書く意味・・・?
/** dayjs読み込み */
@JsModule("dayjs")
@JsNonModule
external fun dayjs(): dynamic
残り日数計算
を含めた完全版です。
import kotlinx.browser.document
import org.w3c.dom.HTMLInputElement
/** dayjs(コンストラクタあり)読み込み */
@JsModule("dayjs")
@JsNonModule
external fun dayjs(d: dynamic): dynamic
/** dayjs読み込み */
@JsModule("dayjs")
@JsNonModule
external fun dayjs(): dynamic
fun main() {
// 残り日数表示要素
val countdownTextElement = document.getElementById("countdown_text")!!
// ボタン
val calcButton = document.getElementById("calc_button")!!
// 日付入力要素
val dateInputElement = document.getElementById("date_input")!! as HTMLInputElement
// ボタン押したとき
calcButton.addEventListener("click", {
// 日付取得
val dateString = dateInputElement.value
val countdown = dayjs(dateString).diff(dayjs(), "day") as Int
countdownTextElement.textContent = "残り $countdown 日"
})
}
これで残りの日数を表示できます。やったね。

書き出す(ビルド)
ターミナルに以下のコマンドを入力すことでHTMLを書き出すことが出来ます。
./gradlew browserWebpack
build/distributionsに書き出されます。

ホスティング
今回はNetlifyにホスティングして公開します。
とりあえずGitHubに公開する
ここから出来ます。

Netlifyで公開
ビルドコマンドのところを空白にします。
おま環だろうけど、Netlifyでビルド出来なかったのでGitHub Actionsでビルドして、結果だけNetlifyに公開するようにする。
ビルドしないように設定を変更します。Site settingsからBuild & deployをおし、Stop buildsします。

GitHub Actions の前に
リポジトリの設定を開いて、Secretsを開きます。
この中に、必要な値を保存しておきます。
NETLIFY_AUTH_TOKEN
Netlifyのアカウント設定へ進んで、Applicationsの中のPersonal access tokensまでスクロールして、New access tokenを押して払い出してもらいます。
NETLIFY_SITE_ID
これはさっき公開したサイトの設定へすすんで、Site informationの中のAPI ID:の値です
こんなふう

GitHub Actions を組む
リポジトリのActionsを選択して、set up a workflow yourselfを押して作成します。

そしたら以下コピペ
# 参考にした。thx!:https://qiita.com/nwtgck/items/e9a355c2ccb03d8e8eb0
name: Netlify
on:
push:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# 権限の変更
- name: Grant permission
run: chmod +x ./gradlew
# HTML書き出し(ビルド)
- name: Making html
run: ./gradlew browserWebpack
# Netlifyにデプロイする
- name: Upload netlify
run: npx netlify-cli deploy --dir=./build/distributions --prod
env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
できたらCommitしてActionsへ移動して見てみます。
作業進行中

終わったらNetlifyで公開したサイトのURLを開いてます。無事開けたら成功です。
終わりに
完成品です:https://countdown-kotlinjs.netlify.app/
ソースコードです:https://github.com/takusan23/CountdownKotlinJS