Glitch で Node 以外のアプリを書く裏技

> :warning: 『裏技 ＝ **オフィシャルにサポートしていない言語で動かす**』なので、Node 以外の言語で書いたアプリは急に使えなくなったりするかもしれません。自己責任で。

# [Glitch](https://glitch.com/) 概要

[<img src="https://cdn.gomix.com/2bdfb3f8-05ef-4035-a06e-2043962a3a13%2Flogo-night.svg" width="120" />](https://glitch.com/)

驚くほど簡単に Node.js アプリを公開できるサービスです。オンラインで JavaScript のコードを書くだけで、`https://[プロジェクト名].glitch.me` に自分のアプリが公開され、他の人と共同編集もできます。

いわば [CodePen](https://codepen.io/) や [JSFiddle](https://jsfiddle.net/) のサーバーレスアーキテクチャ版、といったところでしょうか。詳しい使い方については、以下の記事をどうぞ。

- [[Node.js] 無料で簡単にウェブアプリを公開できるサービス「Glitch」を使ってみた！](https://qiita.com/yonedaco/items/569bcc442872a1f9a03d)

この手軽さに惚れ込み、私も[いくつかアプリを公開](https://glitch.com/@yhatt)したりしています。

# Node 以外の言語を使いたい！

この手軽さを Node 以外のアプリでも享受できれば… と思い、[サポートフォーラム](https://support.glitch.com/)を覗いてみたところ、Ruby の実行に関してこんな証言が。

> Although it’s not officially supported, Ruby is installed, and you can use a custom glitch.json to install and run your app.
>
> *── https://support.glitch.com/t/using-ruby-rails-with-glitch/2576/2*

どうやら Ruby は入っているようなので、**`glitch.json`** を用意してあげれば、アプリのインストール・実行をカスタマイズできるようです。

## `glitch.json`

どこにも文献がありませんので、利用例を探したところ、PHP で利用している例が見つかりました。

> ```json:glitch.json
> {
>   "install": "composer install",
>   "start": "composer start",
>   "watch": {
>     "ignore": [
>       "logs"
>     ]
>   }
> }
> ```
>
> *── https://github.com/cpinheir1103/SandysPetShop/blob/glitch/glitch.json*

つまり、こういうことみたいですね。

|キー|概要|デフォルト|
|:--:|:---|:--|
|**`install`**|アプリインストール時に実行するコマンド|`npm install`|
|**`start`**|Webサーバー起動時に実行するコマンド|`npm run start`|
|`watch`|ファイルの監視設定 (`watch.json` 相当)|[参照...](https://glitch.com/faq#restart)|

`watch` は `watch.json` に相当する設定です。こちらは公式に [Glitch の FAQ](https://glitch.com/faq#restart) に記載されているので、そちらを参照してください。

## 使えそうな言語

2017/12/29 時点で、Glitch アプリのコンソールを開いてザッと調べたところ、以下が使えそうでした。

- Elixir 1.5.2
- Erlang 9.1
- Go 1.7.5
- PHP 7.0.22
- Java 1.8.0
- Python 2.7.12
- Python 3.5.2
- Ruby 2.3.1
- Rust 1.20.0
- Swift 3.0.1

思った以上に揃ってます。3系ですが Swift が使えるのは「おっ」となりました。ちなみに .NET Core (`dotnet`) も入っていましたが、プレビュー版だったのでココには含めてません。

# 実践

## [Ruby + Sinatra](https://glitch.com/edit/#!/ruby-sinatra-example)

<a href="https://glitch.com/edit/#!/ruby-sinatra-example">
  <img src="https://cdn.glitch.com/2bdfb3f8-05ef-4035-a06e-2043962a3a13%2Fview-source%402x.png?1513093958802" alt="view source button" aria-label="view source" height="33">
</a>

**https://glitch.com/edit/#!/ruby-sinatra-example**

Glitch に向いてそうな [Sinatra](http://sinatrarb.com/) を試してみます。

### `glitch.json`

```json:glitch.json
{
  "install": "bundle install --path ./.data/bundler",
  "start": "bundle exec ruby server.rb",
  "watch": {
    "install": {
      "include": [
        "^Gemfile$"
      ]
    },
    "restart": {
      "include": [
        "\\.rb$"
      ]
    }
  }
}
```

Bundler による gem のインストール先を変えていますが、標準のインストール先 (`vendor/bundler`) にインストールしてしまうと、オンラインエディタに内容がズラッと表示されてしまうため、それを回避するためです。

`.data` フォルダは Glitch が提供しているデータファイルの保存先で、Remix（プロジェクトをフォーク）されても、内容は引き継がれません。([参照...](https://glitch.com/faq#db))

### サーバーの記述

[Sinatra の README](https://github.com/sinatra/sinatra) とほぼ同一内容です。

```ruby:server.rb
require 'sinatra'

get '/' do
  'Hello, Glitch!'
end
```

Glitch の場合、環境変数 `PORT` で指定されたポートに Web サーバーを公開する必要がありますが、幸い Sinatra は環境変数を読み取ってくれるので、特にポート設定せずとも動きました。

### 表示

https://ruby-sinatra-example.glitch.me/ にアクセスし、"Hello, Glitch!" が出れば準備完了です。

> ![Screen Shot 2017-12-29 at 22.52.51.png](https://qiita-image-store.s3.amazonaws.com/0/70467/6c7e3006-ff21-7777-1bb3-600dc88f2d96.png)

Ruby サーバーが動作していますね！WEBrick ではうまくルーティングが動作しなかったため、`thin` gem も一緒に導入しています。

あとは Glitch で Ruby アプリを書くだけ！Remix してお試しください。:arrow_down:

<a href="https://glitch.com/edit/#!/remix/ruby-sinatra-example">  <img src="https://cdn.glitch.com/2bdfb3f8-05ef-4035-a06e-2043962a3a13%2Fremix%402x.png?1513093958726" alt="remix button" aria-label="remix" height="33"></a>

## [Go + Echo](https://glitch.com/edit/#!/go-echo-example)

<a href="https://glitch.com/edit/#!/go-echo-example">  <img src="https://cdn.glitch.com/2bdfb3f8-05ef-4035-a06e-2043962a3a13%2Fview-source%402x.png?1513093958802" alt="view source button" aria-label="view source" height="33"></a>

**https://glitch.com/edit/#!/go-echo-example**

同じように Go も試してみました。フレームワークには [Echo](https://echo.labstack.com/) を使用しています。

### `glitch.json`

```json:glitch.json
{
  "install": "GOPATH=$PWD/.data/go go get -v -u github.com/labstack/echo",
  "start": "GOPATH=$PWD/.data/go go run server.go",
  "watch": {
    "restart": {
      "include": [
        "\\.go$"
      ]
    }
  }
}
```

先と同じように、`.data` 内に `GOPATH` を設定しました。

Glitch が提供する `.env` で `GOPATH` を設定すると、パブリックなプロジェクトでは他者にその内容が見えなくなってしまい、Remix した時に正しく動かなくなってしまうので、JSON 内で直接指定しています。

パッケージ管理もシンプルに `go get` で実施していますが、依存が多くなりそうであれば `dep` や `glide` を別途インストールして実行した方が良いかもしれません。

### サーバーの記述

こちらも [Echo のガイド](https://echo.labstack.com/guide) にほぼ準拠しています。

```go:server.go
package main

import (
	"github.com/labstack/echo"
	"net/http"
	"os"
)

func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, Glitch!")
	})
	e.Logger.Fatal(e.Start(":" + os.Getenv("PORT")))
}
```

こちらは `PORT` 環境変数を自動で考慮しないので、node + Express のサーバーと同じように、環境変数を `os.Getenv` で取得してポート指定を行っています。


### 表示

https://go-echo-example.glitch.me/ にアクセスし、"Hello, Glitch!" が出れば準備完了です。

> ![Screen Shot 2017-12-29 at 22.52.51.png](https://qiita-image-store.s3.amazonaws.com/0/70467/6c7e3006-ff21-7777-1bb3-600dc88f2d96.png)

Go サーバーが動作していますね！（内容的に全く同じなのでスクショは使い回しですが...）

あとは Glitch で Go アプリを書くだけ！Remix してお試しください。:arrow_down:

<a href="https://glitch.com/edit/#!/remix/go-echo-example">  <img src="https://cdn.glitch.com/2bdfb3f8-05ef-4035-a06e-2043962a3a13%2Fremix%402x.png?1513093958726" alt="remix button" aria-label="remix" height="33"></a>

## 他の言語

他の言語でも原理は同じで、`glitch.json` で適切なインストールコマンド・サーバー起動コマンドを記述すれば、Glitch 実行環境にインストールされている言語で開発できます。

**"左上のメニュー → Advanced Options :tokyo_tower: → Open Console :tv:"** でアプリ実行環境のコンソールを開けますので、環境確認に利用できます。

# おわりに

改めてですが、**Glitch はオフィシャルでは Node 以外の言語はサポートされていません。** 実際に Node 以外のアプリを作る際は、自己責任でおねがいします。

そうは言っても、JavaScript に慣れていない人でも、手軽な Glitch のアプリ開発環境を体験できるので、個人的な実験等に使ってみるのはアリかもしれません。