KotlinがJSに変換できるとのことだったので、調べたら出て来たYour first Node.js app with Kotlinの記事を追ってやってみました。
ちなみにCLIとVSCodeでKotlin開発を始めてみるメモに引き続きVSCodeとCLIで進めていきます。
環境
- macOS Sierra
- Kotlin 1.1.50
- Gradle v4.2
- Node.js v8.4.0
Gradleのインストール
GradleはNode.jsでいうnpmみたいなイメージです。
依存関係解決してくれます。
インストールはhomebrewでいけます。
$ brew install gradle
$ gradle -v
------------------------------------------------------------
Gradle 4.2
------------------------------------------------------------
Build time: 2017-09-20 14:48:23 UTC
Revision: 5ba503cc17748671c83ce35d7da1cffd6e24dfbd
Groovy: 2.4.11
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_101 (Oracle Corporation 25.101-b13)
OS: Mac OS X 10.12.6 x86_64
無事にインストールできました。
プロジェクトを作っていく
任意フォルダを作って移動
$ mkdir myjsapp
$ cd myjsapp
Node.jsプロジェクトの初期化
$ npm init -y
npm init
でpackage-lock.json
とpackage.json
が出来上がります。
次に必要なモジュールをインストール
$ npm i --save kotlin express
インストールされるとnode_modules
フォルダができます。
$ ls
node_modules package-lock.json package.json
この階層にbuild.gradle
というファイルを作成して次の内容を書き込みます。
group 'node-example'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.1.1'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin2js'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
}
compileKotlin2Js.kotlinOptions {
moduleKind = "commonjs"
outputFile = "node/index.js"
}
次に同じ階層にsrc
フォルダを作成し、その中にmain
フォルダ、さらにその中にkotlin
フォルダを作り、その中にMain.kt
を作成しましょう。
external fun require(module:String):dynamic
fun main(args: Array<String>) {
println("Hello JavaScript!")
val express = require("express")
val app = express()
app.get("/", { req, res ->
res.type("text/plain")
res.send("i am a beautiful butterfly")
})
app.listen(3000, {
println("Listening on port 3000")
})
}
これで準備完了です。
普段Node.jsを書いている人ならval express = require("express")
の箇所からも分かる通りexpress
を使ったWebサーバーになります。
現状ではこんな感じのフォルダ構成になっています。
package.json
やbuild.gradle
ファイルがあるルートの階層でgradle build
コマンドを実行しましょう。
$ gradle build
> Configure project :
Gradle now uses separate output directories for each JVM language, but thisbuild assumes a single directory for all classes from a source set. This behaviour has been deprecated and is scheduled to be removed in Gradle 5.0
at build_b5jf4f0juy83k80loi4m0mzgo.run(/Users/n0bisuke/dotstudio/2_events/20170930_kotlin/myjsapp/build.gradle:14)
(Run with --stacktrace to get the full stack trace of this deprecation warning.)
w: /Users/n0bisuke/dotstudio/2_events/20170930_kotlin/myjsapp/src/main/kotli
n/Main.kt: (9, 20): Parameter 'req' is never used
BUILD SUCCESSFUL in 2s
2 actionable tasks: 2 executed
するとビルドが行われ、build
フォルダとnode
フォルダが出来上がります。
実行
node
フォルダ内のindex.js
を指定します。
$ node node/index.js
Hello JavaScript!
Listening on port 3000
これで http://localhost:3000 にアクセスするとサーバーが立ち上がっていることが確認できます。
i am a beautiful butterfly
って表示されましたか?
変換されたindex.js
変換後のindex.js
です
(function (_, Kotlin) {
'use strict';
var println = Kotlin.kotlin.io.println_s8jyv4$;
function main$lambda(req, res) {
res.type('text/plain');
return res.send('i am a beautiful butterfly');
}
function main$lambda_0() {
println('Listening on port 3000');
}
function main(args) {
println('Hello JavaScript!');
var express = require('express');
var app = express();
app.get('/', main$lambda);
app.listen(3000, main$lambda_0);
}
_.main_kand9s$ = main;
Kotlin.defineModule('index', _);
main([]);
return _;
}(module.exports, require('kotlin')));
感想
最初から最後までCLIとVSCodeだけで書けました。
調べているとGradleやMavenのようなツールが当たり前のように出てくるけど、普段使わないので調べ方で戸惑いました。
この仕組みが実用的かどうかはまだ何とも言えない段階な気もするので、とりあえずはこんなこともできるよってくらいの認識で良さそうです。