no strict

ちゃんとしない。面白いことからやる。

プライベートで毎日コードを書いて、React Native + firebaseなアプリを開発する

以前、React + Node.jsでSPAなウェブアプリを作ってみたので、次はReact Nativeでアプリを作ってみようと思いました。主な構成は以下。サーバレス構成です。

現在は職業的プログラマではないので、コーディングに割ける時間は平日ランチタイムと夜、そして土日のみ。継続することが重要だと思い、余裕のない時でもgithubに無理やり草をはやし続けてみました。 f:id:nostrict:20190208013034p:plain

当初は半年もあれば完成すると思っていたアプリは一年以上経過しても公開に至っていませんが、開発自体はほぼ終わり、結合テストフェーズに入ったことで、ゴールが見えてきました。このあたりで、いくつかの気づきや、反省点を書き残してみます。

新しい言語を使う時は小さなプロジェクトから始めるべき。

2017年秋の時点では、スマートフォンアプリ開発の知識はゼロでした。Reactは多少触っていたものの、React Native、firebase、Algoliaの使用経験はありません。

このようなズブの素人が空き時間にReact Nativeのアプリ開発を進めた結果、このような日程となりました。開発時間は平日2時間・週末5~10時間といったところです。

  • 2017年10月:React Nativeでの画面の作り方調査
  • 2017年11月~12月:DBなしのモックアップ作成
  • 2018年1月~3月:firebase RealtimeDatabaseで仮実装(プロトタイプ)
  • 2018年4月~5月:全体のリファクタリング。firebase RealtimeDatabaseをfirestoreに変更
  • 2018年6月:検索にAlgoliaを導入
  • 2018年7月~11月:実装
  • 2018年12月~1月:UI調整
  • 2019年2月~:結合テスト

当初の3ヶ月は、ほぼReactNativeの学習期間でした。その後の3ヶ月でプロトタイプができましたが、redux/firebaseに慣れてくると初期の頃に実装したDB周りの酷さに気が付きました。リファクタリングすると同時にfirestore化&algolia導入を行ったため開発が長期化する一因となりました。 開発期間が半年を超えたあたりからモチベーションが低下してコードを書く量が減ってしまったこともあり、実装期間は4ヶ月にも及んでいます。

画面数は100以上、書いたソースコードは合計11000行以上、2019年2月8日現在のコミット数は610。最初に作るスマホアプリとしてはあまりにも規模が大きすぎるものでした。

最初は4~5画面程度の小さなアプリを作り、まず公開まで持っていくプロセスを経験しておくべきだったと思います。 (とはいえ、そのようなアプリのアイデアが思い浮かばかなった)

スキマ時間にコーディングを進めると、カオスなコードになりがち

ランチタイムの30分、平日夜の2時間など、細かい時間を見つけてコーディングするスタイルで開発を進めると、「あと15分でこの処理を動くようにしたい」というような焦りが生まれてしまい、場当たり的なコードを書きがちです。また、その後時間が取れないとその事実を忘れてしまうことも多く、全体的な整合性が失われていく結果となりました。

全体の構成を考慮して、目の前の処理を動かすことを優先するのではなく、時には後戻りするような組み立て方をするべきでした。このようなことを考えながら書くには、ある程度まとまった時間集中する必要がありますが、30分を繋いで書いていくスタイルでは難しかった。

細切れの時間で開発すると、前回何を考えていたのかを忘れがちです。個人slackプロジェクトを作ってgithubと連携し、考えていたことをメモしたりコミット内容をタイムラインに流すことで、「何をやろうとしてたんだっけ?」と思い出す時間を削減することができました。

初期にDB周りの設計をかなり細かくやっておくべきだった。

具体的にどのあたりがカオスなコードになっていったかと言えば、それはデータストア周りです。

React Nativeでは、reduxアーキテクチャ、ローカルストレージ(AsyncStorage)、firebase、algoliaという複数のデータストアの連携を意識する必要があり、RDBMSとは異なる設計が必要だと感じました。 次回アプリを作るときは、このあたりのDB設計をもう少し詳細化してから取り組むと思います。

breaking changeのつらみ

React Native系のモジュールは安定していないものが多く、たまに後方互換のないバージョンアップ(breaking change)が行われます。特にreact-navigation周りは大胆な変更が多く、ついていくのが大変でした。モジュールはなるべく最新版に追従したほうが良いと思いますが、バージョン追従にトータルで一ヶ月ほどは費やしている気がします。

現在は、毎日「npm outdated」で最新バージョンを確認し、breaking changeがあるかどうかをチェックしています。

まとめ:継続すれば素人でも大きなアプリは作れる(はず)

上記の気づきは、開発に慣れている人にとってはどれも当たり前のことだと思います。

しかし、プライベートの時間を活用して、どうにかアプリの開発を進められていることや、React Nativeならではの課題・プライベート開発ならではの課題と対策を蓄積するサイクルを継続できている点は、達成感もあります。

今後も、職業的プログラマではない、プライベートベースの開発のやり方を模索していくつもりです。

ランチタイムを開発の時間に当てたら半年でNode.js+Socket.io+Reactを使ったウェブサービスができた話

はじめに

「コードを書いているときが一番楽しい。プログラミングを仕事にしよう。」そう思って就職し、プログラムを書くことでお金をもらうことができた夢のような日々。でもそんな日は長くは続きませんでした。数年のプログラマ生活の後、徐々にマネジメントが主な業務になり、コードを書く仕事から離れてしまい、いつのまにか十年が過ぎました。かつて覚えた技術は、いつしか全て時代遅れになってしまいました。

俺はもっとコードを書く仕事がしたい。 SEだなんてつまらない。なぜか? ..

上記のエントリーにとても共感できました。気力・努力・技術力が足りないために何も書けず何も作り出せず、そんな状況に負い目を感じるような日々を過ごしてきました。

しかし、ある日発想を転換し、時間を確保して手を動かしてみたところ驚くほどスムーズに学習と開発が進み、半年間で最近のトレンドっぽい技術(ES2015/Node.js/Express/MongoDB/Socket.io/React/React-Router/Material-UI)でWebサービスを作ることができました。どれも初めて覚えた技術要素です。

折角なので、この学習プロセスをまとめてみます。

目的

最近の技術を使ってウェブサービスを作ること。

学習・開発方針

普段の生活の時間を削って開発に当てることは負担が大きいので、以下の2つの時間を使うことにしました。

  1. 通過時間に技術系の書籍を読む
  2. ランチタイムは60分きっちり開発に当てる

一念発起して夜中や早朝に時間を確保する、なんてことは自分にはできませんでした。この方針ならほぼこれまで通りの生活で毎日開発時間を確保できます。短時間ですが、毎日のことになるので前日やっていたことを忘れづらいのもメリットです。 ランチタイムを使うことで平日5時間、月に20時間、年間240時間を確保することができます。これだけあれば何かできるでしょう。

前提

保有スキル

10年前にLAMPでWebアプリケーションを作っていたことがあるものの、現在のフロントエンドの知識はゼロ。マネジメント寄りの仕事になっているため、仕事でコードを見ることはありません。エンジニアとしてはそろそろ使い物にならない感じです。

作るもの

昔から興味があったのでなんとなくチャットを作ることにしました。作り終える頃には別のものを作れるノウハウも得られるはずです。

学習・開発プロセス

1ヶ月目:技術の方向性検討〜基礎学習(読書)

チャットということで非同期通信を試してみることにしました。非同期通信でチャットを作る場合、Node.js + socket.ioが定番のようです。このあたりから覚えることにしました。 JavaScript周りの技術を使うことになりそうだったので、まずJS系の書籍を2冊とGithubの書籍を買ってきて通勤時間に斜め読み。なんとなく目を通して雰囲気をつかみました。読み終えたら細かい内容は忘れましたが、全体像がつかめました。

2〜3ヶ月目:プロトタイプ作成

一ヶ月間、通勤時間に技術の本を読んでJavaScriptが書けるような気分になってきました。いよいよ開発をはじめます。 でもいきなり白紙からコードを書くのは無理なので、コピペ駆動開発発動です。

  1. 以下のエントリーに書かれているコードを持ってきてそのまま動かす http://creator.cotapon.org/articles/node-js/socket_io-mongodb-chat-sample
  2. コードをgit/Githubに登録
  3. ソースの一部を修正→動作確認→git commit→動作がおかしくなったら以前のコードに戻す、の繰り返し。 動くものがあれば、少しづつ修正していくことができます。問題が出たらconsole.log()で原因を探って修正。大胆に変更してもGithubに残っているので大丈夫。 具体的には、拾ってきたコードをベースに以下のカスタマイズを施していきました。一から書いたりはできないので、それぞれぐぐって出てきたコードを適当に貼り付けて修正していくだけです。レゴブロックのようなものです。

    • Room分割
    • MongoDB導入
    • デーモン化
    • セッション管理
    • アイコンチャット化
    • LINE風表示
    • 現在の参加者リスト表示
    • BootStrapでデザイン付け
    • React.js/React-router導入

4ヶ月目:期初のため仕事が忙しく時間がとれず。

5〜6ヶ月目:プロトタイプを元にベータ版を再作成

プロトタイプは機能を動かすことを目的に適当にコードをツギハギに足していったものなので、かなり酷いスパゲッティコードになっています。 手を動かしているとES2015、Express、Reactの書き方が多少はわかってくるので、この段階で一旦コードを破棄してゼロから書き直すことにしました。 動いている見本があるので、うまく動かずに悩んだ時にはプロトタイプのコードを見れば解決できます。

プロトタイプからの変更点

  • 基本的にゼロベースで書き直し
  • ExpressのViewをJSXに変更(express-react-views)
  • BootstrapからMaterial-UIに変更
  • 簡単なデザイン付け(CSSで色を変える程度)

完成

以下のチャットサービスができました。シンプルなものですが10年間コードを触っていなかった自分がウェブサービスが作れたと思うと感無量です。

作ったもの→brunch.chat

  • 主な構成要素
    • サーバ周り
      • Docker/Rancher
      • Node.js: v7.10.0
      • MongoDB: 2.6.10
      • express-react-views: 0.10.2
      • socket.io: 1.7.3
    • クライアント周り
      • React: 15.5.4
      • react-router-dom: 4.1.1
      • material-ui: 1.0.0-alpha.20
      • superagent: 3.5.1
      • webpack: 3.0.0

サーバ・クライアントをJavaScript/Reactで統一したので頭の切り替えが不要で楽でした。今後、サーバ・クライアント間でコードの共有もできそうです。 開発環境・本番環境共にDocker上で動かしています。

まとめ

何か新しい取り組みが進まないという場合、マインド不足(精神論)よりもリソース不足を先に解消した方が良いと感じました。 手を動かすことによってのみモチベーションは向上するものでもあり、始める前にモチベーション不足を嘆くよりもとにかく行動する時間を確保し、無計画に非効率にだらだらと手を動かす方が良い気がします。結果的に短期間でモチベーションがあがり、楽しく開発を進めることが出来ました。

通勤時間は読書の、ランチタイムは開発のとても良い時間枠です。この2つの時間を活用することで、半年でウェブサービスを作ることができました。最近のフロントエンドの技術をざっくりと使ってみることもできました。 睡眠時間や土日を削るわけではなく、普段の生活は何も変えていないので特に負担なく開発を進めることができました。今後も気楽に続けられそうです。

ということで、今後もコピペ&ランチタイム駆動開発を続けてみようと思います。 ランチタイムに効率悪くダラダラと手を動かしてみるというやり方、オススメです。

補足:その他読んだ書籍