最近、プライベートな時間をつかってRepostというオープンソースの日報共有アプリケーションを開発しています。
投稿した日報に対して、コメントや絵文字でリアクションすることでチームでのコミュニケーションを活性化させることを目的としています。日報版Slackのようなイメージです。
まだ開発着手から1ヶ月ということもあり、バージョン0.0.1でまともに稼働できる段階ではないですが、開発のモチベーションを高めるためにも記事を書いてみました。
技術スタック
RepostはフロントエンドにReduxを採用し、SPAとして構築しています。APIサーバとしてのバックエンドはRuby on Railsで開発しています。また、エディタ部分はDraft.jsを用いてMarkdownエディタを実装しているところです。
Draft.jsについては、過去にとあるプロダクトに採用した経験があったのですが、当時は拡張性はあるもののつらみの多いライブラリ、という印象でした。ただ最近はDraftJS Pluginsでメンションや絵文字といった機能を導入できるプラグインなども登場しており、これらを実装予定だったため導入してみました。Slateなども候補にあったのですが、どれがよいのでしょうか……。
JavaScriptのビルドについては、今回SPAのためSprocketsを完全に捨ててWebpackerで行っています。本番環境でのビルドでハマったりもしましたが、すんなりと移行できた気がします。一度開発フローが整いさえすれば、webpack-dev-serverの恩恵もあり、フロントエンドの開発効率はとても上がった実感がありました。ただ一定のWebpacker力が要求されるので、その辺りの兼ね合いで選定すればよい気がします。
テストは今回Ruby on Rails標準のスタックであるMinitest+Capybaraで実装しています。テストデータの生成も、Factory GirlやDatabase Cleanerを使わず標準のFixturesを用いています。RSpecは(私の書き方の問題でしょうが)実装する上で悩むことがままあったのですが、Minitestは書いていてとても気持ちいいです。またRails5.1からSystem Testingが導入され、E2Eテストを書く環境が標準で入るようになりました。JavaScriptに対するテストを書く際の特有の面倒さはありますが、Webpackerとの相性もよく、今のところ気兼ねなくテストを書けています。E2EテストがCI上でだけ稀にコケる、といったケースもありますが、Minitest::Retryというライブラリのおかげで安定するようになりました。
本当はReactコンポーネントのテストなども書くべきだと思いますが、開発初期段階のためUIが大きく変わる可能性もあり、開発効率を優先して現状はRails側のユニットテスト+E2Eテストのみを実装しています(という言い訳を……)。
Reduxについては、Reducerまわりの実装にImmutable.jsを導入したかったのですが、アプリケーションの規模も小さくうまみが少なそうだったので一旦保留にしました。今回個人的にやってよかったプラクティスはFeature Componentで、エンドポイントとしてのFeature ComponentをRouterから呼び出し、そこからContainer/Presentational Componentを呼び出す、という構成にすることで問題をシンプルに扱えたような気がします。この辺りの知識については以下の記事がとても役立ちました。
JavaScriptの構造的な設計については、同じスタックであるMastodonのソースコードがとても参考になりました。
なぜつくった
フリーランスの頃、オープンなコミュニティの中で日報を共有しつつコミュニケーションをとりながら仕事できたら楽しそうだな、と思ったのがきっかけです。今は会社員としてエンジニアをやっていますが、社内で開発コンテストがあり、6月の業務時間の一部をRepostの開発にあててよいことになったため、せっかくなのでと着手しました(といっても開発の95%以上はプライベートな時間で行いました)。
ふりかえってみると、ReduxでSPAをつくってみたかったり、バックエンドをAPIサーバとしてのみで構築してみたかったり、Sprocketsを捨ててWebpackerのみで運用するとどうなるか知りたかったりと、技術的な欲求の方が強かった気がします。
あとはRedux+Ruby on Railsの参考実装としてのOSSがあまりなかったので、知見を広めることも開発のモチベーションになりました。
総じて技術的にも学びが多く、アプリケーションに対するご意見をいただく機会もあり、またドッグフーディングしていて便利に感じることも多いので、今後も開発を続けていきたいと考えています。PRやご意見だけでも大歓迎ですので、お気軽にコンタクトいただければと思います。
便利なライブラリ一覧
最後に、Repostを開発する上で有用だったライブラリを紹介します。GemはリポジトリのGemfileにあるとおり代表的なものしか導入していないので、フロントエンド開発で役立ったNode.jsライブラリをまとめてみます。
- redux-axios-middleware: HTTPクライアントaxiosのミドルウェア
- redux-auth-wrapper: 認証・認可用コンポーネント
- redux-form: フォーム用の状態を管理
- redux-localstorage: ストア内の特定の状態をLocalStorageに保存
- react-dropzone: ドラッグ&ドロップ用コンポーネント
- react-fontawesome: フォントアイコン
- react-infinite-scroller: 無限スクロール用コンポーネント
- reactstrap: Bootstrap v4用コンポーネント
- react-text-truncate: 文字の丸め処理(日本語も対応)
- remark-react: MarkdownをReactコンポーネントに変換
- classnames: コンポーネントへのクラス名付与
- to-snake-case: 文字列をsnake_caseに変換