Reactで管理画面を作る際のComopnentライブラリ選定メモ

考えをまとめるためにメモ。

目指すところ

  • 手早く・楽して作る

アプローチ

  • 全部自分で作る
  • CSSフレームワークを自前でラップし、その他は単目的ライブラリを探して使う
  • Bootstrap/Material Designなどを実装したライブラリをベースにしてその他を自分で作ったり単目的ライブラリを探して使う
  • 全部入り(管理画面用コンポーネントライブラリ)を使う

全部自分で作る

文字通り、デザインもCSS書くのも動きをつけるJSを実装するのも全て自前でやる

メリット

  • 全て自分で制御できるので、ライブラリ使っててよくある「これが出来ないの困るんだけど」みたいなことにならない
  • ライブラリ探しとか考えなくていい

デメリット

  • UIデザインが出来ないと話にならない
  • とにかく実装に時間がかかる
  • クオリティ担保が大変

CSSフレームワークを自前でラップし、その他は単目的ライブラリを探して使う

BootstrapなどのライブラリのCSSを自前で作ったComponentに記述して使う

メリット

  • JSの世界については全て自分で制御できるので、ベースになるCSSフレームワークの制御をかなり自由に実装できる
  • CSSフレームワークの恩恵(Gridレイアウトを簡単に使える、ちょっと洒落たデザインをすぐ実装できる)を得られる
  • マイナーなCSSフレームワークで、React実装がないものでも自分で実装するので関係なく活用できるので選択肢の幅が広い

デメリット

  • 全て自前実装に比べてマシだけどやっぱり実装が大変
  • 大抵の場合jQueryとの共存を考える必要がある
  • ライブラリくささが出る(Bootstrap感を隠せない感じ)

Bootstrap/Material Designなどを実装したライブラリをベースにしてその他を自分で作ったり単目的ライブラリを探して使う

reactstrapなどを使う

メリット

  • Gridなどを簡単に実装できる
  • 最低限作るのに道具が揃ってるのである程度手早く実装できる

デメリット

  • ライブラリくささが出る
  • bs,mdのComponentライブラリの細かいデザイン調整は案外手間がかかるっぽい(あんまり詳しくないけど)

全部入り(管理画面用コンポーネントライブラリ)を使う

CoreUIなどを使う

メリット

  • 提供されているものの範疇で実装するなら一番手軽
  • 定番のUIライブラリとちょっと違ったデザインを利用できるのでただBootstrapを使ったものと差別化できる

デメリット

  • 有償のものが多い
    • =利用者が多くないので、利用方法の模索が大変そう・バグを踏んだときが不安
  • React Componentが提供されている物が少ない

上から順に自由度が下がっていく感じ。

今までは手なりで「Bootstrap/Material Designなどを実装したライブラリをベースにして〜」でやってきたけど今回はどうしようかなあ

最近覚えたりやったりしたことを列挙

こんなことやったなぁを書いておこうと思った。

Scala

型クラス

ぶっちゃけプロダクトでどう使えばいいのか全然ピンとこなかったのでもう忘れた...
型クラスがあることによってどんなことを型で表現するからメリットになるのか?の例が知りたい

scalikejdbcとscalikejdbc-bigquery触った

この辺

github.com

ついでにtypesafe-configとかも。
当初の目的としてはscalikejdbc-bigqueryをゴニョるために触った感じ。
普段のプロジェクトではいろいろなライブラリを使ってる関係で生scalikejdbcを触る機会が全然ないので適当に触って、クエリを発行できるようになるまでどんな手順でやればいいのかとかを適当に触った

=:=

型の同一性チェックができる(雑)

mockitoのeqをscalaで使う

Scalaには eq が存在してるのでインポート時に別名でインポートしないと使えない(ハマった

ScalaからCLIツール(具体的には gsutil コマンド)を叩く実装を書いた

要件として、

  • コマンドはなるべく複数並列で叩きたいし、並列数も制御したい
  • コマンドが応答しなくなったら並列で実行中のプロセスをkillしてからScalaのプロセスもちゃんと落としたい

というのがあって、Futureで並列度を制御しつつ、プロセスをkill出来るような実装を頭悩ませて実装したりした
jsでもCLIのラッパー書いたことあるけどキツかったので、CLIのラッパーはどの言語でやってもきついのかもしれない・・・

infra系

Ansible少々触った

  • task,role,inventoryあたりの概念多少知った
  • ユーザー定義の関数を作れるらしいと知った(作ったことはない)
  • スクランナー化したAnsibleは地獄だと知った(弊プロダクトのインフラはそうなってしまっている)
  • 変数の出処を探すのが大変なのでシンプルに保とうという気分になった
  • あと宣言的になるように、とかね。。。

CloudFormation少々触った

  • スタック・変更セット・アウトプット・userdataあたりの概念を知った
  • 順当に運用するのが普通に難しいということがわかった
  • Ansibleに比べて変更の頻度が少ないし、作り直しみたいなことも普通はしないので、「冪等性を保つ」のが意識されにくい
    • 最新のテンプレートだけを反映すればOKという状態になっていない不具合が起きてしまっていた
    • 作って壊してを頻繁に実施するような運用にしたほうがいいのかもしれない
    • インフラ系は触り始めて日が浅いので、ベストプラクティス・・・というかうちの事情を踏まえた上でどうすれば改善できるのか?というのがあまりわからない
  • GCPのDeploymentManagerも多分似た話があるんだけど、こっちは今いるプロダクトだとCFnよりさらにめったに触らないので逆に問題が起きにくい感じがある

Storage Transfer Serviceを毎時集計に使うようにした

EMRでサマった結果をBQでロードするためにS3→GCSへ移動するのに利用。
どうやらこのTransfer ServiceはGCP上の共通のリソースを使っているらしくて、他のProjectがTransferのリソースを使いまくってるときにこちらもアオリを食らうということがあったりしてひどい目にあった
アレ本番運用で定常的に使ってる人がいたらどうしてるのか聞きたい・・・

なおうちはgsutil rsyncコマンドで対処できるように、という対応をしました

CircleCI

この辺↓のことをやった

qiita.com

qiita.com

社内ISUCONが楽しかった話

8/17に社内の催し物としてISUCONをやりました。
楽しかったのでやったことを書き起こしてみます。

なお、問題は以下のY!SUCONから出題でした。 github.com

自分のスキルセット

  • フロントエンドエンジニア
  • ここ1年半ぐらいスクラムマスターやってた
  • 最近はScalaで集計周りのコードを書いたりインフラ周り(主にAnsibleやCFnなど)をほんのちょびっと

ISUCONで動けるタイプの人間じゃない・・・

事前準備

チームのメンバーが、主にアプリケーションエンジニアだけど上から下まで一通り触る競プロマンと機械学習系が強いマン。
相談した結果、競プロマン氏がインフラやらミドルウェア周りを中心、自分と機械学習マンでひとまずアプリ周りという方向になりました。

アプリはいったん自分が得意としてるJavaScript実装でスタートすることに。

リポジトリの用意・最低限の環境構築・ブラウザで業務用に開いてるタブを閉じるあたり。

本番

競技時間はおおよそ10:00開始で17:00にベンチ用のインスタンスのシャットダウン
開始時間がおおよそなのは朝は集まりが悪いので時間が確定しにくい問題があったりなかったり

10:00 ~ 10:30

  • とりあえず落ち着いて開発できる席を探して着席したら.ssh/config作ってインスタンスへログインできるように確認
  • ひとまずベンチ回す
  • アプリコードをリポジトリにいれてpushしたりデプロイスクリプトの作成に入ったり
  • アプリコード読んだり

こんな感じでエンドポイント列挙したりした f:id:sisisin444:20180817235351j:plain

10:30 ~ 12:00ぐらい

(若干時系列バラバラ

  • alpやらnginxのアクセスログやらを見れる環境を用意
  • アプリをローカルで動かすのがんばったり
  • アプリ側のパラメータ弄るだけで良さそうなところをひとまずなおした(mysqlのconnection limit1 -> 10)
  • 計測してなかったんで重いエンドポイントわからんかったけど /searchが怪しそうとアタリを付ける
  • マイクロサービスになってたアプリの統合をした方が良さそうだったので、ひとまずDBが分かれてたのを統合した

    • アプリ側はまだ普通にマイクロサービスへリクエスト投げまくってる
  • 11:30ぐらいに計測結果が出て、 //searchがクソ重いことがわかる

    • ここで / を何とかしようという方向に

11:30 ~ 13:30ぐらい

  • 競プロマンがとりあえずとってきたtweetsテーブルの結果だけuserテーブルをクエリしていたのでJOIN
    • ここでベンチが全然数字変わらずハマる。
    • デプロイスクリプトがバグっていたのが原因っぽい
    • ・・・と思いきやちゃんとデプロイしても数字伸びない
  • その間自分はマイクロサービスをモノリシックにする修正を入れたり
    • 何故かBadGatewayが出てハマる
    • ローカルでは動くし原因がわからない・・・
    • 1時間ほど慌てた結果、全部モノリシックにするのは諦めて、GET /:meだけを統合(POST,DELETEで使ってるエンドポイントの follow, unfollowはそんなに重くなかったので)したら通った
  • モノリシック化をいれてベンチするけどあんまり変わらず(たしか1000ぐらい)。もっと重い部分が別にあったのでこれは予想通り
  • friendsテーブルの正規化をやるかどうかを悩んででかい実装になるので今からこれやりきる自信がないと判断してやめ。

(ここまでスコアは全く伸びてないので地味に焦り始めてました

13:30 ~ 14:30ぐらい

  • 他の人は重いクエリを調べたり考えたりしていたっぽい(自分はあんまり把握してない)
  • 自分はJOINで絶対数字上がるはずだと思って、競プロマンの書いたJOINをさらに修正
    • WHEREにnameの検索を追加
    • LIMITを追加

ここでベンチして7000点を記録する。
他のチームが2000~3000ぐらいをうろついてたので頭一つ飛び出たのでヨッシャになった。
が、エラーが出ていたので全員で何とかしようという話に(今回のレギュレーションではエラーが出てると0点扱い)

14:30 ~ 15:00ぐらい

  • どこがエラーなのかさっぱりわからん状況が続く
  • 競プロマンがnginxのログを見て500返したり返してなかったりを発見
    • nginxのconfをここで初めてまともに見る
  • worker_processesが1になってていかにも怪しいのでとりあえずautoにした
    • ベンチが9000点になってエラーなしを記録してガッツポーズ
  • ↑の修正は / に閉じていたので、 /searchにも適用した
    • 検索条件はいったんLIKEで
    • 15000点ぐらいになった
    • が、またエラーが出る

15:00 ~ 16:45ぐらい

この時間はずっとエラーが出ていた奴と戦っていた。

またアプリじゃなくてミドルウェアが怪しいだろうという事でミドルウェア周りを手分けしてチューニングする方向で調査

innodb_buffer_pool_size = 1G
innodb_flush_log_at_trx_commit = 0
innodb_flush_method=O_DIRECT
  • 静的ファイルをnginxで返すようにしたり
  • 本当にアプリのエラーじゃないことを確かめるためにアプリにloggerを仕込んだり(ここを自前で実装せざるを得なかったのが自分のサーバサイドnode経験のなさの表れだったなあという気持ち)

他チームの追い上げもあったのでなんとしても通したいという気持ちだった中、とあるチームが突然45000点を出してきて無事死亡の気持ちを得る。

16:45 ~ 17:00

  • ミドルウェア周りのエラーだろうと思ってアプリのパフォーマンスをわざと落とす実装を入れてベンチ回したりする悪あがきしてた
    • 結局何度か回してエラー出たのでやめた
  • nginxで弄れるところないかを一生探し続けていたけどだめだった
  • 45000点のチームが何度かベンチして点数をどんどん下げてきていたので何らかの事情でrevertしてるんだろうという感じで、ワンチャンまだある!!!って感じだった

が、結局15000点のベンチを通せずじまい。
最終的に、15:00頃に通った9000点前後のスコアとなった。

結果発表

16:30頃に45000点ぐらいを出したチームが17000点程度まで落としたものの、優勝となった。
うちは9000ぐらい。

お気持ち↓

お開きになった後に反省会で話したこと

  • nginxのアクセスログじゃなくてエラーログ見たら?と指摘されて、見てみたら「Too many open files」が出ていたのを発見 以下の記事を参考に worker_rlimit_nofile をいじったら22000点でた

nginx で Too many open files エラーに対処する - Shin x blog

ぐぬぬぬぬぬぬぬぬ・・・・

  • アプリのloggerは真っ先に入れとくべきだった
  • 完全モノリシック化を諦めたのはナイス判断だった
  • ミドルウェア周りの知見なさすぎて辛かった
  • 想定回答とか見ても全然ベンチの伸び方がかみ合わないんだけど~ってなってた
    • 他のチームもJOINしたりインデックス張ったりしてもベンチ伸びないって言ってた
    • 結局どこがボトルネックなのかよーわからんかった。
  • 足回り整理マンほんと助かる・・・
  • 自分が割と取りこぼしありつつもゴリっとやるタイプで、チームメイトが問題発見とかが得意なタイプだったので自分の弱点を補ってもらえたなぁという気持ちがあった
  • めっちゃたのしかった!

感想

フロントマンが活躍するシーンあるんかいなって感じだったけど、アプリの改善ポイント多めに用意されてた感じがしたので、わりかしやれた感を得られて楽しかった。
そもそも自分はハッカソンやらみたいな限られた時間で精一杯やるってのが好きなので、全力で走った後の心地よい疲れがたまらんですね。
珍しくブログ書くぐらいには楽しかった。

社内ハッカソンでカバレッジ率のバッヂ出すサービスを作った話

うちの職場では3か月に一度程度の頻度で1営業日(7.5h)使ってハッカソンを開催しています。
ハッカソンでは各自で作りたいものを考え、一人あるいはチームを組んで1日かけて物を作ります。
1日の最後には各制作物についての発表をし、投票を行って得票数の多かったチームには後日表彰・賞品の贈呈を行います。

今回自分は2人チームでハッカソンに取り組みました。
その成果物についての紹介と当日の振り返りをしたいと思います。

やったこと

カバレッジ率の情報を持ったjsonAWS lambdaに投げつけたらShields.IOからバッヂのsvgファイルをもってきてS3に配置するサービスを作りました

モチベーション

背景として、社内のリポジトリでサーバサイドとフロントエンドが同居するときにカバレッジの計測・保持・バッヂの出し方をどうしようという話が上がっていました
うちの職場ではcoverallsというサービスにてカバレッジ結果を集計しているのですが、これが1リポジトリに対して1つしか計測結果を保存してくれない。(2つ以上保存する方法あったら教えてほしいです><)
そのため、最近計測できるようになったフロントのカバレッジをどうやって可視化しようかという議題が出ていたわけです。

そんなタイミングでハッカソンが近づいていたので、バッヂ出すだけなら1日あればいけんじゃね?と思ってやってみました

成果物

リポジトリ

opt-tech/zoi

(名前は完全にzoiって言いたかっただけ(あと命名は一緒にやった相方氏

ハッカソンの発表資料

speakerdeck.com

*スライド内での「しめにゃん」は自分を、「あきむらさん」はチームの相方を指しています

サービスの詳細

サービスの役割としては、カバレッジ率についての情報を持った指定の形式のjsonを受け取ったらそれを元にバッヂを生成(create or update)してくれるという薄いものになります。
バッヂのURLは[固定URL]+[指定したバッヂ名]という形式で、バッヂを出したい側でその辺は管理してね、というスタンス

薄いがゆえに自由度が高く、例えばmasterブランチとdevelopブランチについてのカバレッジを別々に投げつけてやれば、それぞれ別のバッヂとして出してやることも可能です

アーキテクチャ

(スライドより引用)

f:id:sisisin444:20161224224307j:plain

実際に適用したサンプルリポジトリsisisin-sandbox/ngts

今回作成したサンプルではこんな流れでバッヂが作られます

GitHub
-> Circle CI
-> put json to S3(ここから先はzoi)
-> execute lambda function
-> put svg file to public S3

GitHub,CircleCIの部分は、[更新したいタイミング]で、[S3へjsonをputできる]ものであれば何でもよいです。

課題とか今後追加したい機能とか

  • 少なくともjsonのフォーマットぐらいはドキュメント化する
  • クライアント側の導入を楽にするために必要な道具を充実させる
    • 冷静に考えて、CIにaws-cli入れてcredential情報入れてjson組み立ててaws s3 cpするとかめんどくさい
    • さすがにエンドポイントはAPI Gateway使うほうがいいかなあ
    • lcov形式のファイルを渡せばそれっぽいjson生成してくれるcliをnpmかなにかで提供できると大分楽になりそう
  • コードの整理とか
    • テスト書いたりデプロイ自動化したりしておきたい

振り返り

良かった

ハッカソン内で問題を解決しようという気持ちが強く働いた

  • 目標設定が良かった
    • (7h * 2人)でちょうど終わるぐらいの規模感
    • 完成した形(=ゴール)がきちんと明確になっていて、それに向かって全力を尽くすことが出来た
  • ぎりぎり終わるかどうかなので、きちんとした段取り、作業のリスクや方針決定、コンフリンクトのない(=お互いの作業をブロックしない)協力体制などを相当真剣に考えた
    • -> 普段だいぶ甘えて仕事してることが浮き彫りに
    • -> 逆に言うと普段からこのぐらいやればもっと効率改善できるなという気付きが得られた

今回のような目標を達成できるかどうか微妙なラインというのは、問題解決に取り組む姿勢にも相当強く影響を与えてくれたと感じられた。
達成のために相当頑張ろうとするので、適切な目標を立てて本気で取り組むという行為は自分にとってめちゃくちゃ良い刺激が得られるのだと分かったのは大きな収穫だったと思う。

反省点

大勢において反省点はなく、細かい点がいくつかぐらい。

  • この時間までにこれが終わってないといけないから時間切ってここまでやろう~みたいな、時間ベースでの段取りは出来なかった
    • -> 結果的に上手くいったものの、きちんと締め切りからの逆算はするべきだった
  • たとえ小さいコードでもきれいなコード書いとかないとリファクタや機能追加で即座に死が見えた
    • lambdaのコードは手元ではノーテストでデプロイ後の環境でのみ確認できるという時間が結構長く続いたため修正が結構大変だったりした
      • -> 小さい確認サイクルを取るための準備は多少面倒なものでも必ず用意したほうが良い。一日の短い時間でもそれが感じられたので本当に2,3時間で済む作業でなければやるべき。
    • 途中の段階で汚いけどいったんマージを決行したのは多分ミスだった
    • -> リリースのためにテストなしや多少のことには目をつぶるというよくあるメソッドは本当に罪深い

その他気付いたこと等

  • 手を普段から動かすことの大事さは本当に実感

    • どういう書き方がいいんだろう・・・みたいな立ち止まりを減らしてくれるのはやっぱり手を動かした時間。
  • ペアプロで得られるものが大きいという実感(問題解決の方向性とか、気付きや見習う点、など)

    • 例えば、途中にハマったポイントがあり、二人で一緒に解決しようとしたときの話。
      • 相方は知らないAPIを使う時まず公式Docを読む人だったが、自分は今回の状況(aws sdkという恐らく変わりづらいAPI、問題設定への解決方法がありふれたものなので日本語情報が割とありそうという雰囲気)から、先に日本語情報を拾いに行った結果サクッと解決できた問題があった。
    • -> 教訓としてはおそらく環境・文化の温度観を察してどの情報源を取りに行くのが効率良いのかという嗅覚を磨くと問題解決への時間短縮につながりそうという感じ?
    • 普段の業務においてはたいていの場合においてあきむら氏の公式のドキュメントを読みに行くのが正しいと思う
  • 成功体験を一つ得られてうれしかった(三度目の社内ハッカソンだけどちゃんとやりきれたのは初めて

おわりに

というわけで大変たのしかったハッカソンでした!
今回良い教訓が得られたのでちゃんと身に付けていきたいですね。

あとはzoiの方もちゃんと面倒見て行ってあげたいところ。
がんばるぞい

SCRUM BOOT CAMP THE BOOK読んだメモ

最近弊社でスクラムを取り入れるという話になり、気付いたら始まっていたので遅ればせながらスクラムについてキャッチアップしていこう運動を始めました。
手始めにSCRUM BOOT CAMP THE BOOKを読み始めたのでそのメモをば。

なお、タイトルが「読んだ」になってるけどまだ途中です。

プロダクトバックログの見積もり

開発メンバー全員で、ポーカーなどを用いて相対見積もりで数字を出していく作業。
この際重視しているのは、話し合いをすることでメンバーが対話を出来る状態になることや、目を多くして見落としをなくすことの模様。 以下、見積もり上でのポイントっぽいところ

  • 作業量を相対的に見積もる
  • 基準となるユーザーストーリーを一つ決め、その基準を元にストーリーポイントという単位で見積もる
  • 見積もりそのものは割りとえいやでやってしまって良くて、誤差を気にするよりも手早く終わらせることを優先
  • 詳細にやるのは優先度が高い、直近でやるべきユーザーストーリーに対してのみ。
  • 見積もり上で疑問・不明点があり、それが解消できないと見積もれないものについては無理に数字を入れなくとも良い

スプリント計画MTG

2部構成になっており、1部でスプリントで着手するユーザーストーリーを提示、2部で作業の実現方法を話し合う。

一部

  • POがプロダクトバックログから今回のスプリントで着手するユーザーストーリーを提示
  • その際に要件の説明や、完了定義を説明、開発メンバーと意識合わせをする

二部

  • 開発メンバー全員でタスクの洗い出しと詳細な見積もりを行う
  • なるべく詳細なタスクに分割し、1タスクにどのぐらい時間がかかりそうかを見積もる
  • スクラムでは計測した結果を元にした予測がキモになるので、ここでは詳細で具体的な計画にすることを心がける

デイリースクラム

ここで報告する目的はスプリントにおいての「検査」であり、進捗報告ではない
スプリント目標を達成するために、新たに問題が出ていないかを毎日検査する

  • 15分を必ず守るようにする
  • スクラムマスターはデイリースクラムの少し前にメンバーに声掛けするなどしてスムーズな進行を心がけると良い
  • 問題発見の場であり、問題解決の場ではないので、解決のための案だしなどが始まるのはNG
  • 問題が見つかったら、デイリースクラム終了後に必要なメンバーで対策の話し合いをすぐ行う
  • 問題発見さえできればいいので、PO/SMはいなくても良い。

スプリントレビュー

POが完了条件を満たしているかを確認する場

  • 要は認識合わせの場っぽい
  • なので、動くものを見なきゃ認識あってるかわからないよね、という話になる模様

今日のところは一旦ここまで。

カタロムのCSVからチェックリストをスプレッドシート用に整形するスクリプトを書いた

Github

github.com

モチベーション

  • Rubyちょっと触ってみたかった
  • コミティア行くときは、毎回マップを印刷しないでリストをスプレッドシートに転記して・・・って作業をしてたので自動化したかった

足りてないところ

スプレッドシートに直接ぶち込みたい