2021/08/22 Zli x SGG 学生合同LT大会 にて発表
2021年のKotlin入門Zli x SGG 学生合同LT大会
View Slide
自己紹介HN: マヤミトID: yt8492会津大学 学部4年去年までZliの代表やってましたGitHub: https://github.com/yt8492趣味: Kotlin, Twitter, ウマ娘今月既にウマ娘に8万を溶かしていますTwitter: yt8492
今回はKotlin布教回です
Kotlinを知ってる人何ができる言語か知っていますか?
今回のLT(セッション?)では2021年現在Kotlinでどんなことができるか紹介したいと思います
思いついたやつとりあえず列挙してみた- Androidアプリ- iOSアプリ- デスクトップアプリ- サーバーサイド- Webフロント- CLIツール- ゲーム
Androidアプリ開発- おそらくKotlinと聞いて大多数の人が思い浮かべるのがこれ- 2019年、GoogleがKotlinをAndroidアプリ開発の推奨言語にすると発表- 今新規アプリをJavaで書いてる企業はヤバい- 従来のJavaで書かれたAndroid SDKやライブラリをKotlinからそのまま使えるだけでなく、KotlinのコードもJava側から簡単に呼び出せる- Jetpack Composeでモダンな宣言的UIの手法で開発ができるように(後述)
サーバーサイド開発- Spring BootやSparkなどのJavaのフレームワークがほぼそのまま使える- KtorというKotlin製のフレームワークもある- 最近だとサーバーサイドにKotlinを採用している企業も増えてきている
なぜKotlinはJavaと相互運用が可能なのか?- KotlinのコードがコンパイルされるとJavaのバイトコードになる- IntelliJ IDEA / Android Studio の機能でJavaにデコンパイルすることも可能- 最終的なランタイムはJVM- サーバーもJARファイルにしてしまえば Kotlinの環境がなくてもJavaのランタイムさえあれば動かせる- Androidも最終的にはapkになる
Kotlinの特殊なランタイムがない→Javaのバイトコード以外も吐き出せるようにすれば任意のものが作れるのでは?
正解
Kotlin/JS- KotlinのコードをJavaScriptにトランスパイルする技術- targetにbrowserとnodejsがある- Gradle経由でWebpackを使い、JavaScriptのファイルを生成する- Gradle経由でnpmを使うことができ、JavaScriptのライブラリなどをKotlin側から使うことも可能- kotlin-react というKotlin/JS向けのReactラッパーライブラリがJetBrainsのGitHubのリポジトリでOSSとして開発されている
Kotlin/Native- Kotlin/Nativeにはいくつか種類(target)がある- iOS- Windows- MacOS- Linux- wasm- targetによっても何を生成するかが変わる- iOSはObjective-Cとxcodeproj- Windows, MacOS, Linuxでは実行可能なバイナリ- wasmはwasm
Kotlin Multiplatform- Kotlin/JVM, Kotlin/JS, Kotlin/Nativeから必要なtargetを指定し、共通のKotlinのコードから各プラットフォーム向けにコンパイル(トランスパイル)する- expect / actual という仕組みがあり、型定義だけを共通のcommon srcに置きプラットフォーム依存のコードはプラットフォームごとのsrcに書くことで、プラットフォーム依存のコードも共通の処理に組み込むことができる- 特定のプラットフォームに依存しない共通のビジネスロジックなどを書くのにcommonモジュールをKotlin Multiplatformで作ると便利
ここからは実例を紹介します
自作ブログJSファイルがクソデカ(約3MB)なのでWi-Fi環境でのアクセスをオススメします😇https://blog.yt8492.com
プロジェクトの構成- 4つのGradleのモジュールから構成されている- common- JVM, JS, MacOSをtargetにしたKotlin Multiplatformモジュール- ユーザーや記事などのモデルの型定義- このモジュールをserver, webfront, cliの3つのモジュールから読みこむ- server- Kotlin/JVMのモジュール- Ktor- webfront- targetをbrowserにしたKotlin/JSのモジュール- kotlin-react, Ktor Client- cli- targetをMacOSにしたKotlin Multiplatformのモジュール- Kotlin/Native, kotlinx-cli, platform libraries, Ktor Client
プロジェクトの構成serverKotlin/MPPcommon- モデルの型定義- JSONの型定義webfront cliPOSIX
commonbuild.gradle.ktsのkotlinセクション
common各プラットフォームから呼び出す共通の型定義
webfront- kotlin-wrappersというリポジトリにある各種ラッパーライブラリを使用- kotlin-react- kotlin-react-dom- kotlin-react-router-dom- kotlin-styled- kotlin-css- ラッパーが提供されていないライブラリも使いたい- 自分で書く😇- react-markdown- remark-gfm- react-syntax-highlighter
JSライブラリのラッパーの作り方1. ライブラリをimplementationするreact-markdownの場合implementation(npm("react-markdown", "5.0.3"))
JSライブラリのラッパーの作り方2. ライブラリのコードを読む(TSの型定義があると楽)
JSライブラリのラッパーの作り方3. 読んだコードをもとにラッパーを書く関数名などはJS側の定義に合わせる必要がある(変える場合は@JsNameで元の名前を渡す)
ReactをKotlinで書く- JSXではなくKotlinのDSLで書く
server- 普通のKotlin/JVMとKtorでサーバーを書いてる- build.gradle.ktsでビルド時に生成したjsファイルを成果物に含めるスクリプトを書いてる
OGP対応- ページのHTMLのヘッダーにOGPの情報を含める必要がある- SPAで記事ごとにOGP出すのしんどい😇- NginxなどでHTMLファイルを配信するやり方ではしんどそう 🤔- Ktorでkotlinx.htmlを使い、HTMLだけサーバー側で動的に生成することに- OGPの生成はJavaのAWTで動的に頑張ってます😇- もっといい方法あったら教えて下さい……
OGP対応
cli- macosX64をtargetにしたKotlin/Nativeのプロジェクト- 管理ユーザーログイン、記事の投稿・編集・削除の機能を実装- ビルドすると実行可能なバイナリになる
各種コマンドの実装- kotlinx-cliを使用- コマンドライン引数などを簡単に扱うことができる- これのSubcommandを継承したクラスを実装し、 main関数から読み込んで使う
ファイル操作など- platform librariesを使う(実質C言語😇)- file pointerなどをゴリゴリに使うので便利関数で隠蔽するのがおすすめです
マルチプラットフォームはいいけど、クロスプラットフォームはできないの?
(がんばれば)できます💪
Jetpack Compose- Android のネイティブ UI を構築するための最新のツールキット(公式より)https://developer.android.com/jetpack/compose- Kotlinと宣言的UIでAndroidのネイティブ開発ができる- stableリリースされた- 最近Android界隈で流行っているので調べると記事が結構出てくると思います
Compose for 〇〇 の登場- 去年11月、Compose for Desktopが登場- Kotlin/JVMで動く- Swing上でSkiaを動かしている- 今年5月、Compose for Webの登場- Kotlin/JSで動く- DOMベース- Android, Desktop, WebでUIのコード共有が可能に(ココ重要)
UIコード共有の例
UIコード共有の例commonandroid desktop web
問題点- ルーティングをどうするか- Androidにはnavigation-composeがある- AndroidのNavigationの仕組みに依存している- DesktopとWebどうする🤔- ルーターがないとキツイ- 既存のライブラリのラッパーを書く?- 自分で実装するのはしんどい
Decompose- Kotlin/MPP向けの、プラットフォームに依存しないlifecycle-awareなビジネスロジックコンポーネント+ルーターを提供するライブラリ- https://github.com/arkivanov/Decompose- 豊富な対応target- Android- JVM- iosX64, iosArm64- macosX64- tvosX64, tvosArm64- watchosArm32, watchosArm64, watchosX86, watchosX64- JavaScript
Decomposeでルーティングを実装する- ルーティングを表す型を定義する- 直和型を使うと便利- ルーティングに引数をもたせたい場合はここで定義する- ルーティングごとのビジネスロジックコンポーネントを定義する- ViewModelみたいな役割にするとよさそう?- ルートのコンポーネントでルーティングの型からコンポーネントへのマッピングをする- ルートのComposable関数でコンポーネントからページごとのComposable関数へのマッピングをする
TODOアプリを実装してみよう
ルーティングを表す型を定義する
ルーティングごとのコンポーネントを定義する
ルーティングの型からコンポーネントへマッピングをする
コンポーネントからComposable関数へのマッピング
各プラットフォームから参照する
サンプルリポジトリ- https://github.com/yt8492/todoCompose- 公式のサンプルよりシンプルに作っています- もろもろ雑だけどゆるして……
まとめ- KotlinはAndroidアプリ開発のためだけの言語じゃない- サーバーもWebフロントもCLIもできる- 超頑張ればクロスプラットフォームなアプリ開発もできる
みなさんもKotlinを始めたくなりましたよね?^^