グラデーションを許容するフロントエンド(ツール)生存戦略
by Pasta-K pastak.icon
自己紹介
https://gyazo.com/26c0fa4d0fa2d8dadcfd5642a3bccb39
NotaではGyazoでエンジニアをやっています
フロントエンド推進番長的な役回りもある
アジェンダ
Gyazoのフロントエンドのこれまでと現状
Gyazoのフロントエンドを未来に進めるための戦略について
移行できるところから移行していく
ちょっとくらい残ってても気にしない
Gyazoのフロントエンドのこれまで
約5年前のKyoto.jsでの発表資料
Gyazo自体は約12年ほど運営しているウェブサービス
React: 2015年〜
2019年にはbrowserify+gulpからwebpackへ
一方それからの間に…
Reactのデータフローも様々なものが世の中で提案されてきた
実際、社内の別のサービスでもFluxというよりはEventEmitter+Data Cacheみたいな構成になっている
Rails側のAPIはrepresenter(RailsのModelをJSON向けにシリアライズする層)を用いてJSON APIが設計されている
フロントエンド側でレスポンスに型を付けて安全に扱うために、徐々に型を付けていった
representerの名前とそれが返す結果を、極力そのままTypeScriptに持ち込んでレスポンスに型を付けている
ひとまず愚直にRailsが返すものをそのまま詰め込んだオブジェクト型を列挙してある
その後にレスポンスを受けて、React側のフックなどで便利な形に再整形している
ここはもう少しフロントエンド側に最適化した形(例: SWRしやすい形にする)でエンドポイントなりレスポンスなりを改善しても良いかもという気持ちはあるpastak.icon ツールや依存の入れ替え
前述の資料を書いた頃も基本方針として
規模がそんなに大きくないので、ツールも依存もどんどん入れ替えてアップデートしていく
どんどん入れ替え続けられると新陳代謝的にやっていけるが、常に新しいものに飛びついていく訳にもいかないので、実際にはある程度は停滞してしまう
この停滞を脱するためにグラデーションな変化を許容するというか寧ろ志向するように取り組んでいる
グラデーションな変化を志向する
移行するために全ての工数を注げるわけではない
技術スタックとしては常に「良いと思うもの」を受け入れられる状況でありたい
2つ以上の似た役割のものを共存させれるように戦略を練って導入をする
もちろんデメリットとして2つ以上のものが共存してしまうので、複雑になったりはするがそれは過渡期の辛さということで受け入れる
それを乗り越えた先のメリットを追い求める
未来に進めるために
大胆にしっかりメスを入れていきたい
ツールや設計の変更を受け入れることは次の議論に繋がる
常に変化させていくことでコードの品質や設計の方針について常にアイデアを出し続けられる環境
例えば、今のGyazoチームのフロントエンド設計の方針は
シンプルなインターフェイスや共通化された構造を意識した設計を標榜して、これまで使っていたComponentなども整理したり、Componentのカスタマイズ性は寧ろ棄却したりしている
グラデーションな状態で混ざるよりは「式年遷宮」出来ると便利なのはそう……
定期的に一部、または全てをリプレースする
リプレース時にモダンな技術にし、メンテナビリティを高める
リプレースの過程で、ドメイン知識を継承し、チームのスキルを維持する
Gyazoの中にはあらゆる場面で「画像を並べる」という表現方法がある
微妙に箇所によって使われているComponent自体が違えば、微妙に体験も異なっている
「画像を並べる」ためのComponentを作って式年遷宮可能に
順次置き換えていっています
実はインクリメンタルサーチ結果一覧などは新しいコンポーネントですyuiseki.icon
このときに要件やモデルを整理した
渡せる画像を表現するデータの型を統一
画像サイズの決定は画面サイズからある程度良しなに
実装はCSS Flexboxでシュッとやる
ツールチップの表示の有無→どこでもツールチップはあると便利
対象全てをしっかり「式年遷宮」出来ると良いけど…
既存の設計の複雑度
そこが発揮している価値の重要度
影響範囲
FlowからTypeScriptの移行をグラデーションにやっている話をします
新旧入り乱れた状態を受け入れる
「がんばらないTypeScript」で置き換えるという話もあるが…
別に全部を置き換えなくても良いのでは
Flowがある状態で新しいコードをガンガンTypeScriptで書いたり出来る環境にすることで、移行するとどう嬉しくなるかを示しておく
共存していることのデメリットはもちろん理解した上でそれを敢えて受け入れる(後述)
触らぬ神に祟りなしという言葉もあるが……
ここは新陳代謝アップさせていきたいという気持ちはある
FlowからTypeScriptへ移行
まずはpastak.iconが実際に新しいコードをTypeScriptで書いて投入して、こういうメリットがあるよ〜って見せていっていた
まだ全ては移行できていない
https://gyazo.com/c3937bb1d74798950a3cad2f73949a13
移行しきるモチベーションが低い
滅多に変更されない古いコードがFlowのまま残っていることが多い
こういったコードは往々にしてテストがないので書き換えるのが辛い……
本当は歯を食いしばってやれれば良いのだけど…
極論すると見た目や振る舞いが変わってないことを保証できるなら、buildやデータフロー自体の変更は受け入れられる
そういう立場に立っているとも言う
Visual Regression Test自体の詳細についてはここでは割愛します
興味ある人居たら次回以降のTechConfなどで誰かに紹介してもらうので、アピールお願いしますpastak.icon
結構様々な工夫をして頑張っていますyuiseki.icon
ちなみにPercyというBrowserStackがやっているSaaSを使ってます 一部だけでもツールや設計を新しくしていく
Flowでない部分はesbuildで高速化している
意図的にボトルネック化させて、移行後のご褒美を明確にする
拡張子で識別可能なように .flow.jsにリネームしたりした
様子(実物からかなり省略しています)
code: webpack.config.js
rules: [
{
},
{
exclude: [
/\.flow\.jsx?$/,
],
use: [{
loader: 'esbuild-loader',
options: {loader: 'tsx'},
}],
},
]
code: jest.config.js
transform: {
'\\.flow\\.js$': 'babel-jest',
'(\\.tsx?|(?<!\\.flow)\\.js)$': 'esbuild-jest',
}
そのほかにも…
useContextやuseSWRを使う
Functional ComponentでClass ComponentをWrapする
CSS Modules
技術選択・方針立案はちゃんとやる
ツールを選ぶときに他のもので代替可能か、差し替えが出来るかは比較的重視している
(もう戻すことは絶対に無いが)FlowとTSも両方とりあえずbabelに食わせれば良かったので、シュッと受け入れられた
なので、esbuildも今はwebpackのloaderとして利用している
これを外した方がもっと嬉しいことは分かっているが、シュッと採用できて、シュッと外せるように
新たな設計を取り込む際もどのように差し込むか、どこと置き換えるかの作戦を立てる
一部のComponentだけでも採用できる仕組み
既存の設計との互換性や一時的な共存出来るように
ミドルウェア的なものを同時に用意したり…
DDDの腐敗防止層的な感じ?
We are hiring!!!!!
まとめ
グラデーションな状況になることを見据えて、それをしっかりと受け入れるというマインドで、フロントエンド(ツール)設計をなんとか前に推し進めようと常にしています
チームに向けては未来のカタチ・どうなりたいかという夢を具体化して見せていくことで興味関心を引く
実際に体験したり導入することでそれがキッカケになって前に進む力を得る
本当はグラデーションな状況の方が無いほうが良いので、一緒にGyazoやNotaの各種フロントエンド設計やツールチェインをやっていく人を募集しております
ここに書いてくれても良いです↓