AndroidStudioでKotlin/JS(Node)を使う(WebPack不使用)

# 概要

[前回の記事](https://qiita.com/riafeed/items/ae45f8a0b0caf1892e1e)でWebPackを使ったKotlin/JS(Node用)のトランスパイルがAndroid Studioでできるようになりましたが、
可能であればわざわざWebPackを使わずに実現したいと考え色々探していたところ、ヒントになる記事を見つけたのでさらに発展させてみた記録です。

https://sakebook.hatenablog.com/entry/2020/04/25/185155?utm_source=pocket_mylist

# プロジェクトの作成

「New Flutter Project」からプロジェクトを作成します、できない人はFlutterプラグインをインストールする必要があります。

新規プロジェクトのGradleタブから、「Kotlin DSL ビルドスクリプト」「Kotlin/JS for Node.js」の2つにチェックを入れた状態にして「次へ」をクリックします。

「名前」に適当なプロジェクト名を入れて「完了」をクリックするとプロジェクトが作成されます。

# kotlinソースコードとフォルダの作成

Kotlinソースコードは`src\main\kotlin`フォルダを作成してその中に作成します。

# build.gradle.ktsの修正

ここではWebPackを使わず、タスク1つで[前回の記事](https://qiita.com/riafeed/items/ae45f8a0b0caf1892e1e)とほぼ同様にJavaScriptを出力するビルドスクリプトになるように修正します。

```build.gradle.kts
plugins {
    id("org.jetbrains.kotlin.js") version "1.7.20"
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    implementation(kotlin("stdlib-js"))
    implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7")

    //使用するNodeモジュールがある場合はこのようにして追加
    //implementation(npm("express", "4.18.2"))
}

kotlin {
    js {
        tasks {
            //ビルドオプションの設定
            compilations.all {
                kotlinOptions.moduleKind = "commonjs"  //モジュールシステムの設定
                kotlinOptions.sourceMap = false        //ソースマップの生成
                kotlinOptions.metaInfo = false         //metaファイルの生成
            }

            //出力ファイルのコピー
            val jsMove by creating(Copy::class) {
                dependsOn(build)
                from("build/js/packages/${project.name}/kotlin/${project.name}.js")
                //出力先フォルダの設定
                into("output")
                //出力先ファイル名の設定
                rename { it.replace("${project.name}.js", "${project.name}.js") }
                mustRunAfter(build)  //これを入れておかないと順番が保証されないらしい。
            }

            //トランスパイルしてコピーするタスクをまとめて実行
            register("jsBuild") {
                dependsOn(build, jsMove)
            }
        }

        nodejs()
    }
}
```

JavaScriptにトランスパイルするタスクは`compileKotlinJs`なのでこのタスクを実行するようにすればいいと思ったら「そんなタスクはないです」と怒られるのでどうしたものかと思ったのですが、`build`タスクを実行するように依存設定すればうまくいきました。

# Android StudioでGradleタスクを実行

Android StudioのGradleツールバーの「Gradleタスクの実行」ボタンからgradle jsBuildを実行することでトランスパイルができます。

```
gradle jsBuild
```

トランスパイルされたJavaScriptコードはoutputフォルダ内に作成されます。

# ちなみに

```Main.kt
external fun require(module:String):dynamic

fun main() {
    println("Hello JavaScript!")

    val express = require("express")
    val app = express()

    app.get("/") { _, res ->
        res.type("text/plain")
        res.send("i am a beautiful butterfly")
    }

    app.listen(3000) {
        println("Listening on port 3000")
    }
}
```

このコードをトランスパイルすると、

```main.js
(function (_, Kotlin) {
  'use strict';
  var println = Kotlin.kotlin.io.println_s8jyv4$;
  var Unit = Kotlin.kotlin.Unit;
  function main$lambda(f, res) {
    res.type('text/plain');
    return res.send('i am a beautiful butterfly');
  }
  function main$lambda_0() {
    println('Listening on port 3000');
    return Unit;
  }
  function main() {
    println('Hello JavaScript!');
    var express = require('express');
    var app = express();
    app.get('/', main$lambda);
    app.listen(3000, main$lambda_0);
  }
  _.main = main;
  main();
  Kotlin.defineModule('KotlinNodeMinimum', _);
  return _;
}(module.exports, require('kotlin')));
```

こんな感じになります。
WebPack版とは違い、minifyはしないので必要なら別で手動で実行するかminify用のタスクを作る必要があります。

# githubリポジトリ

これも手動でファイルの作成や修正をしないで済むように最低限の設定とファイルの作成を済ませてあるプロジェクトファイル群をgithubにアップロードしました。
クローンするなりZIPダウンロード・展開してインポートするなりするだけで(初期ビルドに時間がかかるっぽいのですぐにとはいきませんが)Kotlin/JS(Node用)の開発をAndroid Studioで始めることができます

https://github.com/uniras/KotlinNodeMinimum