文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

新サイトstring-utilityをリリースしました

誰もいい感じのサイトを作ってなかったので、私がやってしまったよ


f:id:treeapps:20170918135756p:plain

本日新サイト、string utilityをリリース致しました。

内容は、サイト名見たまんまで、文字列操作に関するユーティリティーサイトです。

では色々と解説していきます。

新サイトのURL

www.string-utility.com

まだtwitterカードやSEO等をろくに設定していません。

多分動くと思うからリリースしようぜ!」と偉い方がおっしゃっていたので、リリースしました。細かい事は後からリリースしていきます。

更に言うと、まだ1機能しかありません。後日機能を増やしていきます。

システム構成

インフラ Google Appengine Standard
ランタイム Java8
サーバサイド:言語 JetBrains kotlin v1.1.4-3
サーバサイド:フレームワーク Spark Framework v2.6.0
サーバサイド:ビルド Gradle v3.4.1
クライアントサイド:言語 Typescript v2.5.2
クライアントサイド:フレームワーク Angular4
クライアントサイド:ビルド yarn, angular-cli v1.4.5
アーキテクチャ シングルページアプリケーション
UIフレームワーク angular material v2.0.0-beta.10
スタイル sass
証明書 マネージドセキュリティSSL
ドメイン Google Domains beta
サーバ維持費 月間¥116(ドメイン代のみ)

ざっくりこんな感じです。全体的にGoogleフレンドリーな要素で固めています

前回作ったtree-mapsでは、GAE/Golang、reactだったので、今回は最近正式リリースされたGAE/Java8とangularを使ってみました。

気になるGAE/Java8のスピンアップ〜フレームワーク初期化〜JSONを返すまでの速度をGAE/Golangと比較した記事は以下をご覧下さい。

www.bunkei-programmer.net

何でこのサイトを作ったのか

たまーに文字数をカウントしたい時があり、ウェブ上で「文字数カウント」と検索して使っていたのですが、これが実に使いにくい。

「カウントする」というボタンをクリックしないとカウントできないし、カウントできる種類も少ない。更に「何がヒットしてその文字数なのか」も不明。これはいけない。この程度はできて欲しいぞ〜、と考え、もう私が作ってやる!と思って、実際に作りました。

技術要素について

GAE/Java8の解禁

折角GAE/Java8が解禁されたという事は、SpringBootやSpark Frameworkも解禁されたという事で、どちらかを使おうと思いました。SpringBootはフルスタックで、今回はサーバサイドはほとんど使わない想定なので、非常に高速でシンプルなSpark Frameworkを選択しました。

Spark FrameworkはJavaのマイクロフレームワークで、Jetty9が内蔵されています。起動速度はJavaの中で最速の部類と思われ、450ms程度で起動が完了します。hot reloadやDIの機能は内蔵されていませんが、不要なものは一切無く、必要なものを必要なだけ足す事ができる優れものです。

JavaはJVMの初期化が遅く、更にGAE上でスピンアップも遅いので、せめてフレームワークの初期化は速い方が嬉しいので、SpringBootではなくSpark Frameworkが最適であると判断しました。

Kotlinも解禁

Java7の時から実は使えたのかもしれませんが、今回公式サンプルでもkotlinバージョンが用意されており、これは正式にkotlinサポートがされたな!と確信できたので、今回は素のJava8ではなく、kotlinを採用しました。丁度IntelliJ IDEA Ultimateを購入済みなので、早速最高の環境でkotlinを始める事ができました。

kotlinについては以下の本を読んでおけば大丈夫だと思います。

Kotlinスタートブック

Kotlinスタートブック

更に、IntelliJ IDEA Ultimateを使っている場合、javaのコードをkotlinのファイルにペーストすると、なんと自動的にkotlinのシンタックスにコンバートしてくる凄い機能が備わっているので、「あれ?javaでこう書く時、kotlinだとどうするんだ?」という時は、とりあえずJavaのコードを貼り付けると解決する場合が多いです。

主役であるフロントエンド

今回のサイトはリアルタイム性がサイトのテーマなので、サーバサイドは基本的に使いません。全てjavascriptのみで処理します。ルーティングもangularで行いますし、文字列処理もtypescriptでゴリゴリします。

angularについてはこのサイトを作る前に以下の本を購入し、読了済みでした。

Angularアプリケーションプログラミング

Angularアプリケーションプログラミング

上記angular本は凄く良く出来ており、これ1冊読めばとりあえずSPAサイトは作れると思います。(node.js以外との組み合わせはちょっと難しいですが)

typescriptですが、私の場合は既にreactをやった時に、ES2015,ES2017を経験済みだったので、ほぼ同じ書き方で動いてくれるので、特にこれといって勉強は必要ありませんでした。せいぜい「typescriptってどんな型があるのかな?」と調べる程度です。

webpack氏〜・・・

tree-mapsの開発時はcreate-react-appのような便利ツールも無かったので、手動でwebpackをゴリゴリ書いていたのですが、これがまた辛い!超辛い!あれを手動で書くのは職人芸です。正直もう2度とゴリゴリしたくありません。

という事で今回のangularでは、angular-cliで楽をする事にしました。実際楽で、ng g component XXX のように簡単にscaffoldできるし、実際フル活用しています。

しかしですね・・・

webpackがクッソ重い!!重すぎる!!

もう地獄のようなコンパイルの遅さです。

webpackのコンパイルがあまりにも遅いので、それに激怒した人達がFuseBox等を作ってしまう程の遅さです。

github.com

create-react-appとangular-cliは非常に優れた良いツールだ。しかしwebpack、貴様は駄目だ。

fuseboxやrollup.jsに乗り換えるという手もありましたが、私は標準構成が好きなので、現在の標準であるwebpackに甘んじる事にしました。

地獄のコンパイルの遅さに耐えながら・・・

angular-material氏〜・・・

reactの時はmaterial-uiを使っていて、公式じゃないのにこれは凄いUIコンポーネントだなあと軽く考えていました。

今回公式であるangular-materialを使ってみたわけですが・・・

品質低っく!!

と思いました。

material-uiと比較するなんておこがましいにも程があるレベルの差があると思います。

まだv2がベータ版だからこの程度なのか、それともGoogleがangular-materialの事を全く考えていないのか、謎です。コンポーネント数が少なすぎるし、コンポーネントの構造も練られていないせいでカスタマイズしにくいし、リファレンスも解りにくい(このコンポーネントを動かすために何をimportしたらいいか書いてない)。

Google先生本気出してくれませんかね・・・

reactと比べてangularはどうだった?

私はangularの方が性に合うと思いました。

propsと@Input,@Output

reactの場合はコンポーネントのプロパティ宣言にPropTypesを宣言しますが、実際のプロパティから物理的に離れた位置に宣言するのに対し、angularの場合はプロパティに@Input(), @Output()といったアノテーションを定義する形になります。これは個人的に非常に解りやすくていいと思いました。

コンポーネントとhtmlとcss

コンポーネントとhtmlとcssの関連についても、最善ではないのかもしれませんが、私はangularの方が解りやすいと思いました。所謂以下のことです。通常angular-cliが勝手にこれらを作ってくれるのでほとんど触らないです。

@Component({
  selector: 'app-change-log',
  templateUrl: './change-log.component.html',
  styleUrls: ['./change-log.component.sass']
})
export class ChangeLogComponent implements OnInit {
JSXと*ngディレクティブ、キモいのはどっちだ?

断然*ngディレクティブの方がキモいと感じました。

angularの場合はループ処理を以下のように記述します。

<div *ngFor="let matche of halfNumericMatches">
    <span>{{matche}}</span>
</div>

reactの場合は以下のように記述します。

<div>
    {this.state.halfNumericMatches.map((matche) => {
        return <span>{matche}</span>;
    })}
</div>

私は両者を見て、reactの方が直感的で解りやすいと思いました。

reactの場合はES2015のmapを使ってループを処理しているのに対し、angularは*ngForという独自のシンタックスです。

標準好きな私はどうしてもreactの方に惹かれます。

まあどちらにもメリット・デメリットはあると思うので、個人の好き嫌いであると思います。

Routerについてはどう?

angularの方が良いです。

reactにはreact-routerがありますが、これがまたじゃじゃ馬で、こいつはreactとreduxに挟まれる存在で、ちょっとreactがバージョンアップしたら動かなくなり、ちょっとredux(react-router-redux)がバージョンアップしたら動かなくなります。

こいつらはしょっちゅうアーキテクチャについて議論されており、ころころ仕様が変わってしまい、それに幻滅して離れた人も多かったとか。実際私もそれに少し巻き込まれ、書き直しを余儀なくされたタイミングがありました。その時は丁度react-redux-routerのバージョンアップにも巻き込まれ、動かすだけでも大変でした。

reactは確かに色々な技術要素を組み合わせる事ができるのですが、組み合わせた時にバージョン間で動く・動かない問題がある(特にreact, react-router, react-redux-router)ので、そこが正直辛いところです。

一方angularの場合はangular-cliでng new アプリケーション名 で開始し、最初から全部入りで必ず動く状態からスタートする事ができます。バージョンアップする際もangular-cliでインストールされるバージョンに従ってバージョンアップしていくと、安全にバージョンアップする事ができます。

まあ、まだreduxを取り入れていないので、取り入れたらreactのバージョン間問題が勃発するかもしれませんけどね・・・

結局angularの学習コストは?

数年前は「angular?学習コスト高過ぎだろ?」なーんて言われてましたよね。

で、今はどうでしょう。

私はReact v15(v16)とAngular v4を触ってみたわけですが、reactの方が明らかに学習コストが高いと感じました。

Angularはangular-cliの登場により、関連ツール・ライブラリは最初に一式揃います。それに対してreactはcreate-react-appを使ったとしても、reactでよくある構成で使うreact-routerやreduxはインストールされません。(reduxについてはangularも同じですが)これが結構大きい差だと私は思っています。

これらは一見するとたった2つのモジュールに見えてしまいますが、実際はreact + redux + react-redux + react-router + react-router-reduxが必要で、それぞれが連携します。前述したように、それぞれのバージョンアップによって何かが動かなくなる事はしょっちゅうあるので、辛いところです。

また、angularがフルスタックであるが故なのか、日本語の書籍もAngularの方が充実しています。Angularの場合はフルスタックなので、1冊に大体の情報が書かれているのに対し、Reactは関連モジュールは何が取り扱われるのかが著者によって変わります。場合によってはreduxを取り扱わない書籍もあるかもしれません。

そうした情報の集約度合いもangularの方が充実しやすいように思えます。そこで「各モジュールの英語リファレンス見ればいいじゃん」と思われるかもしれませんが、各ライブラリがお互いのライブラリのバージョンに気を使っているかどうかはライブラリ次第です。場合によっては「あのライブラリとこのライブラリは辛うじて動いたが、あのライブラリが動かない・・・」となって困ったりする事もあります。

最速・最適を追い求める勢力にとってはreactは非常に都合のいいものですが、そうではないケースではAngularは非常に良い選択肢であると思います。私は標準好きなので、angularに惹かれてしまいますね。一応両方使ってサイトを開発しているので、どちらかに傾倒しないようにはしていますが。

今後の展望とか

まだ1機能しか無いので、少しづつ機能追加していきます。

1機能追加 → 即リリース → 更に1機能追加 → 即リリース

というサイクルで、複数機能を一気に大量にリリース!みたいな日本的な事はしません。できたらすぐリリースします。

次作ろうと思っている機能は、安直ですが、csvとtsvの相互変換機能です。

tree-mapsで緯度経度を入力するtextareaがあるのですが、csvとtsvの2パターンの入力方法を用意しています。この入力支援をしたいので、まずはcsv・tsvの相互変換機能を作りたいと思います。


次は、csvまたはtsvの全ての行の末尾に、特定の項目を追加する機能です。

これもtree-mapsの入力支援機能で、末尾にマーカーコードを簡単に入力する方法を提供できたらなあ、と考えています。

どちらも構想段階なので、その通りに作るとは限らないのですけどね。

雑感

ちゃっかりKotlin + Spark frameworkデビューしましたが、サーバサイドの処理は少ないので、正直「へー」とか「ほーん」程度の感想しかありませんでした。。。

それよりも「angularいいんじゃない?」「typescriptいいじゃん」の方が感じました。

今回ドメインについてはGoogle Domainsベータを使ってみました。つい最近まで日本では使用できなかったようですが、今では日本語UIも用意され、日本でも余裕で使用できます。全部GCPで行きたい人は、Route53ではなくGoogle Domainsを使うのもアリかと思います。

更に、最近GAEにマネージドセキュリティという機能がリリースされ、カスタムドメインさえあれば、SSL証明書が無料で利用可能で、自動的に更新される恩恵を受ける事ができるようになりました。AWSで言うところのACMと同等です。


最近Java9がリリースされ、リリースサイクル関連で賑わっていますが、これからはkotlinがjavaに取って代わる可能性が高いので、是非以下を読んでおくお事をオススメします。

Kotlinスタートブック

Kotlinスタートブック

Kotlin Webアプリケーション 新しいサーバサイドプログラミング

Kotlin Webアプリケーション 新しいサーバサイドプログラミング

Kotlinイン・アクション

Kotlinイン・アクション

  • 作者: Dmitry Jemerov,Svetlana Isakova,Kotlinユーザグループ,長澤太郎,藤原聖,山本純平,yy_yank
  • 出版社/メーカー: マイナビ出版
  • 発売日: 2017/10/31
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

また、angularについては以下を読んでおけば大丈夫だと思います。

Angularアプリケーションプログラミング

Angularアプリケーションプログラミング

Webアプリ構築のためのAngularJS (プレミアムブックス版)

Webアプリ構築のためのAngularJS (プレミアムブックス版)

Angularデベロッパーズガイド  高速にかつ堅牢に動作するフロントエンドフレームワーク

Angularデベロッパーズガイド 高速にかつ堅牢に動作するフロントエンドフレームワーク

私は最近はGoogleAppengineにどっぷりで、VPS等のレンタルサーバは借りたいとも思わなくなってきました。

もはやGAEについて語りませんが、無料でここまでできるので、ちょっとしたサイトをVPSで運用している方は、GAEにも目を向けて見るといいと思います。ただ、BlueGreenデプロイメントやStackDriverやマネージドSSLがあるとはいえ、自分で解決しないといけない問題はやっぱりVPSより多いと思うので、ある程度のスキルは要求されると思います。

しかしそれを乗り越えると、以下程度サイトならドメイン代だけで運用できます!
www.tree-maps.com