Home About Contact
Kotlin , JavaScript , Node.js

やりなおし Kotlin/JS Hello, World! 生成した js を HTML から使う / Node.js から使う

see: Kotlin Multiplatform 1.9.22 Kotlin/JS Hello, World!

昨日、Kotlin/JS Hello, World! Kotlin のコードを Node.js で使う を書いたのですが、 もっと簡単に扱う方法がわかったので再挑戦します。

なお、ここでは Kotlin で書いたコードを HTMLに埋め込んだJavaScriptで使いたい、というライトユースを想定しています。 たとえば、Node.js + React で使いたいなどというヘビーな使い方は想定していません。

環境

$ java -version
openjdk version "17.0.5" 2022-10-18

$ gradle -version
Gradle 7.6

$ node --version
v18.12.0

hello プロジェクト

プロジェクトディレクトリを作成:

$ mkdir hello
$ cd hello
$ touch build.gradle.kts 

build.gradle.kts の内容:

plugins {
    kotlin("js") version "1.7.22"
}

version = "0.1"

repositories {
    mavenCentral()
}

kotlin {
    js(IR) {
        browser {
            webpackTask {
                outputFileName = "hello_lib.js"
                output.library = "helloLib"
            }
        }
        nodejs()
        binaries.library()
        binaries.executable()
    }
}

js(LEGACY) に替えて js(IR) を使用します。 また、browser, nodejs, binaries.library(), binaries.executable() 全部指定しています。 今回の目的(HTMLに埋め込んだJSからKotlinコードを使いたい)の場合、全部の指定が必要かわかりませんが、 まだ良く事情がわかっていないのでとりあえず全部指定です。

webpackTask の部分は、設定しなければプロジェクト名からデフォルトの名前が使用されますが、 それだと困ること(どの名前を指せばいいんだ!的な)が多いので、明示的に指定しています。

それでは、 gradle wrapper しておきます。

$ gradle wrapper

これ以後は gradle コマンドの代わりに ./gradlew を使っていきます。

JavaScript から使うための kotlin コードを書きます。 はじめに所定のディレクトリを作成して、空の Main.kt を用意。

$ mkdir -p src/main/kotlin
$ touch src/main/kotlin/Main.kt

Main.kt

@ExperimentalJsExport
@JsExport
fun greeting(name: String): String {
    return "Hello, ${name}!"
}

それでは build します。

$ ./gradlew build

build/distributions/ 以下に

の2つのファイルが生成されています。 これが Main.kt がJSに変換されたファイルです。

それでは、index.html から hello_lib.js を使います。

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>hello</title>
  </head>
  <body>
    <script type="text/javascript" src="hello_lib.js"></script>
    <script>
        var helloLib = this['helloLib'];
        console.log(helloLib.greeting('World'));
    </script>
  </body>
</html>

スクリプトタグで hello_lib.js をロードすると、this['helloLib'] をハンドルとして greeting 関数が使えるようになっています。

hello_lib.js や helloLib は gradle.build.kts の以下の部分:

kotlin {
    js(IR) {
        browser {
            webpackTask {
                outputFileName = "hello_lib.js"
                output.library = "helloLib"

で指定した名前です。

python3 -m http.server 8000 などとしてウェブサーバを起動して、http://localhost:8000/ にアクセスして コンソールログに、Hello, World! と出力されているのを確認しましょう。

これでHTMLから hello_lib.js を使う方法はわかりました。

Node.js から hello_lib を使う

この build/distributions/hello_lib.js は Node.js からも普通に使えます。

index.js

const helloLib = require('./build/distributions/hello_lib');

const v = helloLib.greeting('World');
console.log(v);

実行:

$ node index.js
Hello, World!

できました。

まとめ

HTML から使うにしても、Node.js から使うにしても、build/distributions/ 以下に生成されたファイルを使えばよいだけなので、 取り扱いが楽です。