Help us understand the problem. What is going on with this article?

KotlinをNode.jsに変換してWebサーバーを作るメモ #teratail_kt

More than 1 year has passed since last update.

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 initpackage-lock.jsonpackage.jsonが出来上がります。

次に必要なモジュールをインストール

$ npm i --save kotlin express

インストールされるとnode_modulesフォルダができます。

$ ls
node_modules      package-lock.json package.json

この階層にbuild.gradleというファイルを作成して次の内容を書き込みます。

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を作成しましょう。

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.jsonbuild.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です

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のようなツールが当たり前のように出てくるけど、普段使わないので調べ方で戸惑いました。

この仕組みが実用的かどうかはまだ何とも言えない段階な気もするので、とりあえずはこんなこともできるよってくらいの認識で良さそうです。

参考

n0bisuke
プロトタイピング専門スクール「プロトアウトスタジオ」で教えたりしてます。 プロフ -> https://dotstud.io/members/n0bisuke
https://protoout.studio
dotstudio
全ての人がモノづくりを楽しむ世界を目指して活動しています。
https://dotstud.io
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした