桜の頃(開発合宿2019 2日目)

おはようございます。

雨模様だった昨日とは打って変わり、抜けるような気持ちの良い朝になりました。

f:id:kokuyouwind:20190411070555j:plain

すこし葉桜が混じっていますが、部屋から見える桜もきれいです。

それでは開発合宿2日目も、実況形式でお伝えしていきましょう。

1日目の記事はこちら。

tech.misoca.jp


(07:30 @kokuyouwind)

f:id:kokuyouwind:20190411073139j:plain:w300

朝ごはん!

あゆ雑炊があるのが長良川っぽいですね。

うぐぅ。

f:id:kokuyouwind:20190411073310j:plain:w300

朴葉味噌もありました。

香ばしくておいしい。


(08:05 thara)

朝ごはんをいっぱい食べました。 お腹いっぱいで眠くなってきました。


(08:35 id:torimizuno)

妖精の働きにより寝てる間に実質終わったようです

f:id:torimizuno:20190411083501p:plain


(08:45 @kokuyouwind)

午後からぷち観光に出たいので、早めに作業を始めに来ました。

f:id:kokuyouwind:20190411084759j:plain:w300

だれもいない会議室!

一番乗りできるのは珍しい。


(09:10 id:mizukmb)

天気良くて最高


(09:20 @ryoKawamata)

朝の散歩がてら岐阜公園よりリエクストリーム出社。
天気が良い日に屋外でPC開くと、画面が非常に見づらいという知見を得ました。

f:id:ba068082:20190411093309j:plain:w500


(09:43 id:mizukmb)

もうだめだ

f:id:mizukmb:20190411094333p:plain:w300


(10:24 id:mizukmb)

完成した


(10:40 id:nezurika)

ダッシュボードにもりもりとグラフが表示されてきています。
モザイクをつけてもギリギリ感あるのでもう載せる画像がない…。


(11:25 @kokuyouwind)

自動アップデートの実装をしてますが、「ビルドに時間がかかって暇」って呟いたら、普段Androidアプリ開発のこまたつ氏から「アプリ開発の気持ちがわかるでしょー?」「Web開発たのしー」と煽られました。


(12:14 thara)

お昼ご飯は天丼でした。

f:id:zetta1985:20190411121618j:plain


(12:30 @kokuyouwind)

こくよう「みずしりさん去年も似たようなこと書いてなかった?」

こまたつ「天丼だけに?」

いまこまたつが面白いこと言ったよ!!!


(12:38 @k0matatsu)

掛け軸になんて書いてあるかみなさん思い思いの方法で解読しはじめた
f:id:komatatsu:20190411124105j:plain:w500
なんて書いてあるでしょうか!?


(12:54 id:mizukmb)

ういろ

f:id:mizukmb:20190411125452j:plain:w300


(13:00 @k0matatsu)

f:id:komatatsu:20190411125837p:plain:w500

成果発表の準備もできたのでもう少ししたらリス村に行きます


(14:04 @mugi_uno)

たった今、一日遅れで長良川の会場に到着したんですけど、 なんかリス村行ったとかで数名いないんですけど!!!


(14:10 @kokuyouwind)

f:id:kokuyouwind:20190411141228p:plain

AutoUpdateできた!

どうでもいいけどpackage.jsonに書くバージョンとして0.0.0がvalidなのを知った。



(15:30 id:mizukmb)

団子おいしい🍡

f:id:mizukmb:20190411152941j:plain:w300


(16:48 id:nezurika)

SQLとSQLのぶつかり合い中ですね

f:id:nezurika:20190411164823p:plain


(17:00 id:torimizuno)

疲労が misoda に出てる

f:id:torimizuno:20190411165841p:plain


(17:00 @kokuyouwind)

気分転換に河原町をお散歩してきました。

いい雰囲気の町並み。

f:id:kokuyouwind:20190411165856j:plain:w300

f:id:kokuyouwind:20190411165827j:plain:w300

f:id:kokuyouwind:20190411165928j:plain:w300

ついでに長良川デパートでうかいボードゲームをゲットしました。

マッチ箱サイズでかわいい。夜に遊びたい。

f:id:kokuyouwind:20190411170402j:plain:w300

河原町にある和カフェに行こうと思ったんですが、16時までで閉店だったので諦めて地元の喫茶店っぽいところに。

2種シャーベットを頼んだら、思ったより豪華なのが出てきました。

f:id:kokuyouwind:20190411170514j:plain:w300

お店の前にいる猫ともちょっと戯れてから帰りました。

f:id:kokuyouwind:20190411170716j:plain:w300

f:id:kokuyouwind:20190411170749j:plain:w300

楽しんできたので、またWindowsと戦いたいと思います。

頑張るぞ!


(18:02 thara)

ロボット水門。 かわいい。

f:id:zetta1985:20190411180317j:plain


(18:11 @mugi_uno)

調子乗ってたら作ったものぶっ壊して、リカバリーに1時間以上かかった。

「終わった〜!観光してこようかな」「この時間だとほとんどお店は閉まってますね」

もうお酒飲みたいです。


(19:00 @kokuyouwind)

電気羊さんチーム、DVDを焼いてマスターアップしました。

夕食は打ち上げだ!!! 飲むぞ!!!


(21:30 @kokuyouwind)

f:id:kokuyouwind:20190411213614j:plain

隠れた鵜匠の才能が明らかになりました。


(23:00 @kokuyouwind)

今日はポケットWi-Fiが回収されたからか疲れたからか、部屋でがっつり作業してる人もおらずとても静かです。

明日は朝から名古屋に帰ることになるので、早めに寝てしまいましょうかね。


(23:00 @lulu-ulul )

今回は全チーム初日に実装終わってるのもあってみんな部屋でまったりしています。 露天風呂に浸かりながらわいわいと話すのは合宿感あって良いですねー。

いつもリモート勤務なので朝の通勤ラッシュに怯えながら寝るとします、おやすみなさい Zzz...。


3日目の記事はこちら。

tech.misoca.jp

雨のち晴れ(開発合宿2019 1日目)

朝からあいにくの天気ですが、Misocaは今日から開発合宿です!

今年は長良川温泉のホテルパークに来ております。

f:id:kokuyouwind:20190410102925j:plain:w300

会議室からの眺め。さすがに雨が降っているのでだいぶ暗いです。

なぜかベランダにたぬきがいますね…

f:id:kokuyouwind:20190410103324j:plain:w300

昨日は晴れていて桜も咲いていたので気持ちの良い堤防道路でしたが、この雨で桜も散ってしまったかもしれませんね。

f:id:kokuyouwind:20190410103138j:plain:w300

さて、去年の記事と同じく、今年も各メンバーからリアルタイム更新で合宿の様子をお届けしたいと思います!


(10:30 @kokuyouwind)

というわけで開発合宿始まりました!

さっそくチームごとに作戦会議からスタート。

f:id:kokuyouwind:20190410103734j:plain:w300


(11:30 @suer)

開始一時間ですが、高度な情報戦が繰り広げられています。

f:id:suer:20190410113617p:plain:w300


(12:00 @kokuyouwind)

自分と@kawamataryo は電気羊㌠として、Misocaのデスクトップアプリを作っています!

すでに @kawamataryo が electron-vueを使って試験実装していたため、実質合宿終わりました。

f:id:kokuyouwind:20190410115803p:plain:w300

インストールメディアも用意してあります!(形から入るタイプ)

f:id:kokuyouwind:20190410120235j:plain:w300

微妙に挙動が怪しいところを直したり、全部WebViewではなく部分的にネイティブでフロントを書き直したりを試していく予定です。


(12:10 @kokuyouwind)

お昼ご飯ですー。

親子丼!

f:id:kokuyouwind:20190410121407j:plain:w300


(13:00 @mallowlabs)

@mallowlabs と @torimizuno の @nezurika は社内の統計ダッシュボードを Redash で作り直すプロジェクトをやっていきます。 すでに Redash が立ち上がり、https でつながるようになったので実質合宿は終わりました。 Redash サーバから分析用の DB に接続できない気がするけどそれは些細な問題ですね。

f:id:mallowlabs:20190410130148p:plain


(13:00 id:mizukmb)

会社支給のポケットWifiが届くまでの間、自分のスマホのテザリングで作業していたのですが早速大量のギガを消費して大変なことになっています。

今はポケットWifiが届いたので大丈夫


(13:33 id:komatatsu)

できた!!!!!!(個人情報が多分に含まれるためキャプチャの掲載は差し控えさせていただきます。) うかいミュージアムいこっと


(13:52 id:torimizuno)

エンジニアに助言をいただきながらデザイナーとマーケッターではじめてのSQLを書き始めました💪 もりもり覚えていくぞ💪💪💪

f:id:torimizuno:20190410135042p:plain


(13:52 @mugi_uno) 自宅からリモートで一人チームで参加しています。 合宿は概念です。

ところで、なんか電卓できました

f:id:mugi1:20190410135707g:plain


(15:56 id:mizukmb)

お腹がすいたので朝コンビニで買ったメロンパン食べてる


(17:15 id:nezurika)

redashでSQLを書き始めました! グラフも作れて、やっぱり見えるものになるとテンション上がりますね。 いまは眼精疲労がつらいですがテンションあがりました!

f:id:torimizuno:20190410171453p:plain


(17:19 thara)

AWS Systems Manager完全に理解した。

長良川うかいミュージアム【公式サイト】 に行こうと思ったけど、もう閉まってました。残念。


(17:30 @kokuyouwind)

Windows用のインストールメディアができました。

f:id:kokuyouwind:20190410173226p:plain

これをこうして…

f:id:kokuyouwind:20190410173246p:plain

こうじゃ!

f:id:kokuyouwind:20190410173346p:plain

Windowsでアプリが立ち上がりました。やったね!

本当はMSIインストーラを立ち上げたかったのですが、Macでビルドしたらどうやってもうまくいかず諦めました。ざんねん。

--

(18:45 @mugi_uno)

どうも富山県自宅合宿組です。

できました。

f:id:mugi1:20190410184412p:plain

娘が部屋に乱入してきたので強制終了です。 また明日!!!


(19:23 id:komatatsu)

おいしい!! f:id:komatatsu:20190410192242j:plainf:id:komatatsu:20190410192302j:plain f:id:komatatsu:20190410192325j:plain


(23:10 @kokuyouwind)

温泉に入ってきました。いいお湯でした。

夕食前くらいから、アプリを再起動するたびにログインが必要になる問題と戦っていたのですが、このworkaroundでセッションを残せるようになりました。

もうちょいいいやり方がある気はするというか、SorceryのRememberトークンがSession CookieではなくPersistence Cookieになってて自動ログインされるはずなんですけどね…

まぁ解決したので、今日はもう作業終えてデレステをやろうと思います。


(23:15 id:mizukmb)

寝ようかな


(23:50 @kokuyouwind)

明日もあるし早めに寝よう。

おやすみなさいー。


2日目の記事はこちら。

tech.misoca.jp

#RubyKaigi2019 ノベルティのお知らせ[ステッカー帳とご当地ステッカーを配布します]

こんにちは、とりみずです。

春ですね。 いよいよ4月…というわけで、RubyKaigi2019で配布するノベルティのお知らせです。

①ステッカー帳

昨年大好評だったステッカー帳を、今年もどどんと配布します。

Misoca社員が持ち歩いていますので、声を掛けてもらえればお渡しできます。

f:id:torimizuno:20190403094344p:plain

制作秘話などは昨年の記事を御覧ください。

tech.misoca.jp

②Misocaご当地ステッカー(4種類)

昨年配布したステッカー帳が好評だったので、それを使って御朱印巡りのようなことができないか…とアイデアが出て、今年はMisocaのご当地ステッカーを作成しました。

f:id:torimizuno:20190401161132j:plain
ご当地ステッカーは全部で4種類

Misocaの各拠点をモチーフにしたステッカーになっています。 Misocaロゴや弥生ロゴもステッカーとして貼れます。

制作風景:福岡といえば?

会場限定ステッカーは開催場所が福岡ということで、「福岡といえば何?」で悩みまくる勢…。 最終的には、公式が🍜のemoji押しだったので🍜に着地しました。

f:id:torimizuno:20190329163349p:plain f:id:torimizuno:20190329163451p:plain

制作風景:ステッカーの紙選び

今回エンジニアイベントで配布するものなので、エンジニアの方に紙を選んでもらいたくて紙のサンプルチェックをお願いしました。

f:id:torimizuno:20190401160523j:plain
紙のサンプルを吟味している様子

最終的には、「和紙が結構いいなと思ってる。なんとなくステッカー帳と合いそう」と意見をもらい、和紙の素材になりました👍

サンプルのブルドックシールが気に入ったようで、紙の吟味後すべてのブルドックシールを回収してmacに貼っていました。

f:id:torimizuno:20190401160639j:plain
無数に並ぶブルドックの様子

制作小話

今回のステッカー印刷は、岐阜にある印刷所のデジタさんにお願いしました。 種類も豊富で値段も優しいので、昔からよく利用しています。

www.digitaprint.jp

🙌さいごに

RubyKaigi2019用のステッカーは今回のイベント会場限定で配布コーナーに設置しますので、ぜひゲットしてください!

名古屋・東京・島根のステッカーは、当日イベント参加する各地方のMisocaメンバー(MisocaTシャツやMisocaパーカーを目印に着ています)が持っていますので、声を掛けてもらえればお渡しできます。 (こちらはイベント以降、各オフィスでもゲットできます💪)

当日のリアルタイムなお知らせは、公式Twitterにて発信していきます。

それではRubyKaigiで会いましょう!

開発環境のECSリプレイスとterraformでのコード化

こんにちは、Misoca開発チームの黒曜です。

先日シャニマスの1stライブで会場限定CDを入手したので、作業用BGMにヘビロテしています。
甜花ちゃんのアルストロメリアが特にお気に入りです。

真面目な近況としては、Rails Developer Meetup 2019に登壇するので発表準備をしてます。

railsdm.github.io

以前@lulu-ululが記事にしていたビジュアルリグレッションテストについて、構成やその後などを掘り下げてお話する予定です。
もしご興味があればセッションにお越しください。

tech.misoca.jp

🐳 環境のDocker化

Misocaのローカル開発環境はDockerで立ち上げられるように整備されているのですが、デプロイ先の環境はEC2になっていました。

これでも問題なく運用できていたのですが、以下のような課題がありました。

  • 逐次更新を積み重ねており現状の構成がわからず、新しい環境は既存の環境からスナップショットを取って立ち上げる必要がある
  • 上記に関連し、OS・ミドルウェアのバージョンを手作業で揃えており煩雑
  • レビュー環境はECSで立ち上げており、他の環境と構成に差異がある
  • 一部システムをマイクロサービス的に切り出しており、各環境でそのサービスを立ち上げ連携させていく必要がある

これらの課題をどうしていくか検討した結果、デプロイ先の環境もDockerコンテナを利用してECSに載せ替えることにしました。
合わせて、この構成をterraformで記述してコード管理できるようにし、新しい環境も立ち上げやすいようにしまています。

この記事では、ECS化でどういう構成になったか、terraformをどのように書いたかなどをまとめていきたいと思います。

🏗 大まかな構成

早速ですが、ECS移行後はこんな感じの構成になりました。*1

f:id:kokuyouwind:20190315104620p:plain

MisocaがメインとなるWebサービス、Backendが裏側で動くAPIサービスです。

概ね既存のEC2インスタンスに載っていたサービスをコンテナ化しただけですが、一部構成を変えた点があるため以下で説明していきます。

Cognitoでの認証

もともと、開発環境を外部から利用されないようmod_auth_openidcでの認証をApacheレイヤーでかけていました。

ECSへの載せ替え後は、ALB+Cognitoを使って同等の認証をかけるようにしています。 この設定はAmazon CognitoユーザープールLambdaトリガーでALB認証のメールアドレスを制限するを参考にさせていただきました。

NATゲートウェイでの外部リクエストIP固定化

利用しているAPIの中に、IP単位での許可申請を行う必要があるものがありました。

以前はEC2インスタンスごとにElasticIPを振って申請していたのですが、ECS化を機にNAT Gatewayを利用して外から見えるIPが固定されるように変更しました。

もちろんこの構成はEC2インスタンスでも可能ですが、既存のインスタンスのネットワーク構成は気軽に変更できないため、ECS化と合わせて実施することができました。

DynamoDBをマネージドサービスに変更

切り出したBackendサービスでは、データストアにDynamoDBを使用しています。

既存の環境ではリザーブドキャパシティを最低にしても負荷に対してコストが高かったため、DynamoDBローカルを使用していました。
しかし2018年11月に開催されたRe:InventでDynamoDBの従量課金が利用できるようになったため、ECSに置き換えるのと合わせてバックエンドをマネージドサービスに置き換えました。

これによりECSコンテナではデータを一切保持しない構成になったため、サービスの破棄・再生成が容易になり、Fargateに載せることもできるようになりました。*2

デプロイ時のCodePipelineソースをECRに変更

図中には示していないですが、サービスの更新にはCodePipelineを利用しています。

移行前は以下のような流れでサービスの更新を行っていました。

  1. CodePipelineでソースの変更を検知
  2. CodeBuildで静的ファイルをビルド
  3. CodeDeployでEC2上のサービスを更新

移行後もCodeBuildの処理をDockerイメージの構築に変えれば大体同じ流れにできたのですが、これも2018年11月のRe:InventでAmazon ECRをCodePipelineのソースにできるようになったため、以下のような流れにしました。

  1. CodeBuildがソースの変更を検知し、Dockerイメージを構築
  2. ECRへの変更をCodePipelineが検知し、ECSのサービスを更新

これによりソースコードをS3経由で受け渡す必要がなくなり、S3へのファイル転送にかかっていた時間を短縮することができました。

デプロイ周りについてはMulti Stage Buildを使ったビルド高速化など工夫した点が多いので、また別の記事でご紹介できればと思います。

🔧 terraformでのコード化

最初のECS環境はAWS Webコンソールから試行錯誤しつつ作ったのですが、きちんと可視化して同様構成も作りやすくするため、terraformでのコード化を行いました。

この際、ネットワークなど各環境で共有するものと、ECSサービスなど環境ごとに必要なものとがあったため、以下のように「共有リソース」「各環境で必要なリソース」を分け、それぞれを1つのterraform stateで管理するようにしました。

ディレクトリ構成は以下のようになっています。

+ misoca-infrastructure
  + misoca-dev-common
  + misoca-dev-envs
  + misoca-dev-review

環境ごとに対応するリソースの分類を以下の図に示します。 この図を使いながら、各ディレクトリで管理しているリソースを説明していきます。

f:id:kokuyouwind:20190315105147p:plain

共有リソース(misoca-common)

一番上の点線で囲った箇所が共有の構成で、この部分は単純に terraform import を使ってコードに吸い出しています。

なお、ALBは複数使用するとその分料金がかかるため、1つのALBを複数の環境で共有するようにしました。各リスナールールでドメインに基づいて環境を振り分けるようにしています。

常設環境(misoca-dev-envs)

真ん中と下はそれぞれ1つの常設環境に対応しており、真ん中が通常の環境、下は外部と連携するためにGoogle認証を外す必要がある環境です。

これらは、 misoca-environment モジュールに渡す変数でリソース定義を変えるようにしています。

module "misoca-test" {
  source = "../modules/misoca-environment"
  name = "test"
  domain = "test.misoca.jp"
}

module "misoca-test2" {
  source = "../modules/misoca-environment"
  name = "test2"
  domain = "test2.misoca.jp"
  require-google-auth = false
}

このようにreqire-google-authを渡し、モジュール側では countを使って作成するリソースを切り替えます。

variable "require-google-auth" {
  type = "string"
  default = true
  description = "use goole authentication"
}

// with google authentication
resource "aws_lb_listener_rule" "forward-to-ecs-misoca" {
  count = "${var.require-google-auth ? 1 : 0}"
  // ...
}

// without google authentication
resource "aws_lb_listener_rule" "forward-to-ecs-misoca-without-auth" {
  count = "${var.require-google-auth ? 0 : 1}"
  // ...
}

他のリソースについても環境によって異なる場合は変数に基づいて切り替えるようにしています。 これにより、misoca-environmentモジュールを使えば任意の設定で環境を立ち上げられます。

レビュー環境(misoca-review)

以前の記事で書かれたレビュー環境についてもterraformを使って管理していきたいのですが、レビュー環境はいくつ環境が必要になるか不明で、単純にコードを書いていくと管理が面倒になります。

そこで、以下のようにterraform workspaceを使って環境を立ち上げるようにしました。

module "misoca-review" {
  source = "../modules/misoca-environment"
  name = "review-${terraform.workspace}"
  domain = "${terraform.workspace}.review.misoca.jp"
}

こうしておくことで、kokuyouというworkspaceに切り替えてから適用すると kokuyou.review.misoca.jp の環境を立ち上げる事ができます。

🤔 困っていること

上記のような構成で概ねいい感じに動いているのですが、ECSの立ち上げ環境をFargateにした結果、サーバにsshしてのコマンド実行ができなくなってしまいました。

特に困るのはデータメンテナンスや開発用のrakeタスク実行、手動でのバッチリトライができないことです。 ECSタスクをコマンド上書きして立ち上げることで一応は可能ですが、vpcやセキュリティグループの設定を揃えるのが面倒なうえ、ちょっとした作業でもFargate起動の時間を待たないといけないという点が不便です。

ひとまずは以下のようなECSタスクを手軽に立ち上げるスクリプトを書いて凌いでいます。

ただ結局Fargate起動にかかる時間がかかるのと対話的な操作ができないのは不便です。

RunCommandやSessionManagerが使えなくなるのは結構痛いんですが、みんなどうしてるんでしょうかね…?

🌈 今後の展望

開発環境のDocker化を推し進めたのは良いのですが、今度は本番環境と乖離してしまっているという課題があるため、本番環境も同様の構成へ載せ替えていきたいと思います。

本番ではログや監視などもしっかり考えないといけないので、開発環境でそのあたりの設定を吟味した上で移行していく必要がありそうです。

また、レビュー環境についてはGitHubにブランチをpushしたら自動で立ち上がる、という部分まではまだ実現できていません。

こちらはJenkinsで新規ブランチのpushを元にterraformコマンドを実行させればできそうかな、と考えています。

📢 宣伝

MisocaではInfrastructure as a Codeを実践したいエンジニアを募集しています!

www.wantedly.com

*1:routerがないとかNAT Gatewayの位置がおかしいとか、いろいろ突っ込みどころがあると思いますが見逃してください🙏

*2:Fargateでは永続化ボリュームを利用できないため、永続化データは外部に持つ必要があります

Figmaでアイデア発散会をやったら盛り上がった件

こんにちは、デザイナーのとりみずです。

最近Misocaでは全社的にデザインツールにFigmaを導入しました。

Misocaではリモートの社員も多く、モバイルアプリを開発しているチームは

  • 東京…デザイナー
  • 名古屋…サーバサイドエンジニア
  • 京都…デザイナー
  • 鳥取…Androidエンジニア
  • 福岡…iOSエンジニア

という日本各地の集まりになっています。

このメンバーで、とある価値仮説に対して「俺の考える最強のアイデアぶつけあい大会」をすることになりました。 そこでFigmaを活用したところ、リモートでのアイデア発散会にとても向いていたので、その様子を紹介したいと思います。

当日までの準備

課題とターゲットをすり合わせを行い、当日のアイデア発散会までの準備に下記を宿題としました。

  • アイデア発散会の日までに各自手書きでアイデアイメージをA1の紙に書く
  • 匿名性を考慮してアイデアに考えた人の名前はつけずにおく
  • FigmaのPageに貼っておく

※この時、どういう形式で書けばいいで迷ってアイデアだしが止まってしまわないよう、サンプルを私の方で用意しました。

f:id:torimizuno:20190222180139p:plain

そして当日…

オンラインミーティングサービスのZoomでFigmaの画面を共有し、俺の考える最強のアイデアぶつけあい会のはじまりです。

このようにZoomでFigmaを画面共有しながら、ひとつひとつのアイデアを順に見ていきます。 最初は匿名性でのジャッジを想定していたのですが、説明がないとわからないアイデアもありましたので、全員が順に自分の書いたアイデアを説明する流れで共有をしていきました。

f:id:torimizuno:20190225141710p:plain

その後、各アイデアのここがよかった!を可視化するため、自分がよいと思った部分や疑問点に、Figmaのコメント機能でコメントをしていきます。 誰かがコメントすると、派生してどんどん意見が生まれていたり、ポジティブなやりとりが発生していているのを見るのも楽しかったです。

Figmaはリアルタイムで同じ画面で誰がどこを見ているかもわかるので、コミュニケーションもより取りやすいと感じました。

f:id:torimizuno:20190225141737p:plain

よかった部分の可視化の後は、似ているアイデアをグルーピングし、特長を書き出します。 この日はあくまでアイデアをぶつけ合う発散会目的でしたので、ここまで終えたところで、最後に全員で次回のアクション決めをしました。

まとめ:figmaでのアイデア発散会は、盛り上がる🎊

ミーティング後、チームのチャンネルでメンバーの感想があがっていたのですが、とてもポジティブな反応があって嬉しかったです。 もちろんアウトプットが重要ですが、会自体が盛り上がり、全員が発言しやすい環境づくりも大切だと改めて感じました。

f:id:torimizuno:20190225110810p:plain

📢採用

Misocaでは、チーム開発を一緒に楽しんでくれるデザイナー、エンジニアを募集しています!

(東京の弥生本社オフィスの拠点紹介ページもできました)

recruit.misoca.jp

Webpackerを導入してから外すまでをふりかえる

こんにちは、@mugi_unoです。

MisocaでjQuery製のフロントエンドコードを書き換え続けていた結果、技術書典6に参加することになりました。現在必死で書いております。

farewell_webpacker

さて、先日とあるブランチがmasterにマージされ、リリースされました。

f:id:mugi1:20190213111057p:plain

farewell : ごきげんよう!、さらば!
farewellの意味・使い方・読み方 | Weblio英和辞書

farewell_webpacker です。

長い間フロントエンドのビルドにはRailsのGemであるWebpackerを使ってきましたが、現在は完全に依存を外しており、純粋なwebpackビルドを行う形に書き換えました。

正直なところ、フロントエンド界隈からは否定的な意見を聞くことも多いWebpackerですが、実際にある程度の期間プロダクションで利用してみて、良いところも辛いところも両方感じることができたので、今回はそのあたりをご紹介したいと思います。

Webpacker導入に至った経緯

Webpackerを導入した際にもこのブログに記事を書いています。

tech.misoca.jp

当時は次のような課題を抱えていました。

  • browserify-railsによるビルドが致命的に遅い
  • ほぼnpmによるパッケージ管理が行われていない
  • アセットパイプラインを使うものと使わないものが混在

とはいえ、それとは別にコードベースにも

  • jQueryべったり
  • Vueが0.12
  • テストコードが存在しない

といった問題を抱えていて、フロントエンドが絡む機能開発に支障が出ていました。 そのため「まずは手っ取り早く基盤周りをいい感じにしたい」という考えから、導入コストの低かったWebpackerを採用することにしました。

🤝 Webpackerのよかったところ

初期導入の敷居が低い

Railsとフロントエンドのビルド周りを組み合わせるのはそれなりに手間です。また、Misocaの場合はフロントエンド専任のエンジニアがいるわけではなく、基本的には誰でもバックエンド・フロントエンドを通してコードを書きます。逆に言うと、フロントエンドのみに全労力を注ぐことが難しいため、シンプルで理解しやすいものが望ましいと考えました。

フロントエンドに限った話ではありませんが、環境構築を行う際には「その後にちゃんとメンテナンスしていけるか?」も重要な観点です。流行っている・使いたい、といった理由だけで導入すると後で痛い目を見る可能性もあります。(流行っている技術を使わないほうがいいということではありません。私も誰も使ってないようなイケてるフレームワークとかガンガン突っ込みたい人です。)

Webpackerが理解しやすいかと言われると正直思うところはあるのですが、少なくともGem側で道を示してくれており「レールに乗って導入しています」というのは情報共有の面では大きいメリットがあります。

また、Webpackerが提供するインストールタスクを利用することで各種設定もすぐに完了するため、「とにかくwebpackを利用したビルド環境をサクっと整えて他の作業に注力したい」という場合には大いに役立ちます。

レールに乗っている限りはコードに集中できる

Webpackerの提供するレールに乗っている限りはフロントエンド側はコードを書くことだけに集中できます。 マイグレーションが発生した場合も、基本的にはCHANGELOGの内容などを参考にしていけばさほど難しくありません。 フロントエンドが好きだったり得意なメンバー以外からすると、フロントエンドのビルド・環境設定周りは苦痛が伴うこともあるため、そこをGem側でケアしてくれるのはとても助かります。

Railsアクセス時の自動ビルドがうれしい

Webpackerはビルド時にコードのハッシュ値を保存しており、アクセス時にコードに差分が発生していると自動的にビルドをしてくれます。 (デフォルトでは開発時のみのオプションです)

「あれ、なんか動かない〜」→「フロントエンド側ビルド忘れてました」 というケースは結構発生するので、それを回避できるのは地味に便利で快適です。

🤔 Webpackerのつらかったところ

レールから外れたカスタマイズがしづらい

レールに乗っている間は快適ですが、そこから外れようとすると厳しい面が出てきます。 たとえば、webpackではwebpack.config.jsというファイルに LoaderやPluginを利用して設定を追加していくのが一般的な方法かと思いますが、 Webpackerの場合は、独自でラップされたクラスを経由してカスタマイズする必要があります。 たとえば、次のようなイメージです。

const { environment } = require('@rails/webpacker')

environment.loaders.append('json', {
  test: /\.json$/,
  use: 'json-loader'
})

environment.loaders.prepend('json', jsonLoader)

module.exports = environment

webpack.config.jsのお作法を覚えなくても良いというメリットはありますが、 そのぶん独自のカスタマイズ方法を把握することになるため、 すでにwebpackに関してある程度の知見がある場合にはコストに感じるかもしれませんし、 最初からwebpack.config.jsの書き方覚えたほうが手っ取り早いのでは?と思ってしまう部分はあります。

また、Webpackerが提供していない範囲でwebpackのカスタマイズが必要になってくると、結局はwebpack.config.js相当のものを引き剥がして書き変える必要が出てきます。

実際には次のようなコードを通してしました。

const webpack = require('webpack');
const merge = require('webpack-merge');

module.exports = function(environment) {
  const defaultConfig = environment.toWebpackConfig();
  const webpackConfig = merge(defaultConfig, {
    /* webpackの設定を独自でカスタマイズ */
  });

  return Object.assign(environment, {
    webpackConfig,
    toWebpackConfig() {
      return this.webpackConfig;
    }
  });
};

このあたりのカスタマイズにはWebpackerが内部で保持しているコードを把握しておく必要があり、 「レールに乗っていればOK!」という状態からはかけ離れてしまいます。

依存関係が見えづらい

Webpackerを使うことで、たとえばbabelを利用したECMAScriptの変換やCSSのビルドといったことは簡単に実現できます。

しかし、そのために必要な依存は@rails/webpackerの内部で閉じられているため、実際のところ何を利用しているのかが若干見えづらいことがあります。

そのため、例えばwebpackプラグインを追加しようと思った際に「すでにWebpacker内部で依存に追加されていないか?」「Webpacker内部での依存バージョンは何か?」といった情報を把握する必要が出てくるため、確認すべきものが多くてつらい、といったことが多々あります。

内部のモジュールのバージョンに引っ張られる

Babelを例に挙げると、@rails/webpacker#v3.5.5 であれば、内部で利用しているBabelは6.x系ですが、本エントリ投稿時点ではBabelはv7.3.3が最新バージョンです。 6.x→7.xの時点で必要となるパッケージ構造などに大きな変更があり、関連して、Babelを利用する他パッケージではBabel6.xとBabel7.xによって設定や挙動に変化があるものが少なくありません。

たとえば、テストフレームワークのJestはBabel6.xのサポートを打ち切っています。 https://jestjs.io/docs/en/getting-started#babel-6

こういった影響を受けて「Webpacker側のパッケージが更新されるまでは、独自で入れたいパッケージが更新できない・あるいは追加できない」といったケースが発生することがありました。(強引にやっていくこともできそうでしたが、メンテナンスコストが増大しそうだったので避けました。)

🎓Webpackerを卒業することにした

さまざまなメリット・デメリットを考えた結果、Webpackerを卒業して純粋なwebpackビルドに置き換えることにしました。

Webpackerの他に追加しているパッケージが増えてきた

テスト環境の整備などを経て、導入初期と比較するとWebpacker以外で独自で導入しているフレームワークが増えてきました。先に挙げた依存関係やバージョンの問題から、「使いたいが使えない・使いづらい」というシチュエーションが発生してきました。

開発環境のDocker化が進んだ

Webpackerの自動ビルドがとても便利で、Rails以外にwebpackプロセスを独自で立ち上げなくて良いのは大きなメリットだったのですが、最近ではDockerによる開発環境の整備が進んでおり、docker-composeを利用することでwebpackプロセスなどは特に意識せずともコマンド一発で起動することが可能になってきました。

マイグレーションコストが高くなってきてしまった

独自でのパッケージの追加や、力技でのカスタマイズを加えていったため、マイグレーションが発生した場合に、CHANGELOGなどを見るだけでは安心できない状態になっていました。 また、Webpacker外のパッケージを更新する際もWebpackerとの影響を考慮する必要があり、気を払わなければいけない対象が多く、それであれば独自でwebpackを構成してしまって自分たちで依存モジュールを完全に掌握できている方が安心だな、という考えに至りました。

結局Webpackerを採用したのはどうだった?

個人的な感想は「採用してよかった」と思っています。

今現在で言えばマッチしない状況があるのは事実ですが、導入初期のころから振り返ってみると、確実に僕たちを助けてくれた存在だったと思います。

初期の設定をWebpackerに任せたことにより、すぐにVue.jsの更新・CoffeeScriptからの脱却・テスト環境の整備といった、プロダクト的にもっと重要な他の改善作業に注力することができましたし、その間はwebpackのことを考えなくて良かったのはとても助かりました。

また、つらかった部分を幾つか挙げましたが、これらはほぼすべてこちら側でカスタマイズしたことに起因して発生しているものであり、本来Webpackerが推奨しているものとはズレており、Webpacker自体の問題とは言えません。先に述べた恩恵のことを考えると、入れ替えるコストを考えても遥かにメリットのほうが多かったと思います。

つまり、プロダクト側の状況が変化したことでWebpackerを使うフェーズからは卒業したんだな、と思っています。Webpackerに限った話ではありませんが、フレームワークにはプロダクトとの相性や、マッチする時期、旬みたいなものがあるので、定期的に見直して最新化していくのは重要ですよね。

というわけでWebpacker、今までありがとう!

📢採用

Misocaでは旬を追いかけるエンジニアを募集しています!

www.wantedly.com

続・Android版Misocaのマルチモジュール対応

みなさんこんにちは、こまたつです。
突然ですが去年のこの記事を覚えていますか?

マルチモジュール化の波にのるべくモジュール分割にとりくんだのですが、しばらくころがしてみてこの分割方法ではイマイチということがわかってきました。
人生には失敗がつきもの、良くない点を整理して次へ進もうと思います。

まず今どうなっているか

冒頭にリンクをはった記事に詳細がありますが、だいたい次のような分割になっていました。

f:id:komatatsu:20190215150308p:plain
旧モジュール分割プラン

文書ごとにモジュールが分かれています。

なにがよくなかったか

まずはこの画面をみてくれ

f:id:komatatsu:20190215150358p:plain
取引先別文書一覧

こいつをどう思う?

すごく...モジュールをまたいでいるんですね。
そもそも各文書は似通ったデータ構造をしているのでクラスも抽象化されています。
これでは文書をさわると分割した別のモジュールにも影響が出てしまい、モジュール分割の恩恵をあまり受けられません。 *1

手間だけが増えてしまいビルドも早くならないし、モジュールをまたぐ画面があるので結合度が高くかえって複雑になってしまいました。

じゃあどうするの?

f:id:komatatsu:20190215150541p:plain
モジュール分割プラン2

これがモジュール分割プラン2です。
Misocaアプリはまだ機能も少ないので、ログインなどの今後追加される機能でも絶対必要な物さえ分離できていればちょうど良さそうというのがわかりました。
秘密の新機能が気になりますよね、私も気になります。

モジュール結合では分割時に追加したものを消したり移したりすれば特に躓くところはありませんでした。
AndroidStudioの表示がおかしいな?と思ったらAndroidStudioを再起動したりcleanしたりしてみましょう。

初挑戦で不安も多かったですが実際に試してみることで、資料を読むだけじゃわからない勘所がつかめました。
時間は失ってしまいましたが、この経験は今後のアプリ開発に活かされることでしょう。

採用情報

Misocaでは一緒にチャレンジしてくれるモバイルエンジニアを募集しています。
失敗を重ねて成功を掴みましょう。

*1:これを考えた当時は見積書だけInstantAppsにできるとよさそうみたいな構想があった