Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロン
ト行く末
約10年前に作られたLIFULL HOME'Sの現行サイト。負債化したJSは何が不十分で負債化したのか、最小限のコストでよりよい設計・規則を
導入するためにどう立ち向かっていくか
2021.03
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
2010年4月入社
アプリケーションエンジニアと入社して10年、現
在はややフロント寄りの業務をしている
学生時代にネトゲで嶌田氏と知り合い、その辺が
きっかけでウェブ開発を始めた
ウェブとDHHが大好き
Nakajima Takuya
Twitter: @nazomikan
大きめレガシープロジェクトのフロント行く末
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
10年前にリニューアル後、以降大きなリニューアルもなく開発され続けてきたサイト(部分的にマイクロサービス化して
いる)
アプリケーション側の技術スタック
• Symfony2
• Twig
• jQuery + Backbone.View的な設計
• Babel/Rollup/Sass/部分的にtypescript
LIFULL HOME’Sのサイト内情
1498 files.
136565 lines.
JavaScript files (ignore library)
おかしいな、さほど大きめではないような…
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
基本的にはBackbone.Viewと同じ考え方
テンプレートパーツと対になるJavaScript側のViewがあって、それ単位で
振る舞いを記述している
Backbone同様にイベント機構の統一などは重なっている
View同士の連携はグローバルなカスタムイベントを使ってやりとりして
いた。
(Backbone.Eventsをグローバル放出してpubsubするのとほぼ同じ)
既存コードでのViewの考え方
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
• コードの流れの統一
• eventsを見ればそのUIの振る舞いがわかる
• 全てのviewでそうなのでリードコストが削減される
• Viewごとの振る舞い定義によるファイル分割 (問題あり)
解決されている問題
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
結局なくならないDOM探索
• DOM探索で埋漏れるビジネスロジック
• セレクタに依存してDOMの変更に弱い
• 似た少し違うコードが量産されて、build時間が増大して
いく
• 横方向の区切りはできても縦方向のviewの境目が守られない
• 安易なDOM探索が子,親viewを犯してしまう
• 親・子分割がうまく行かず巨大な親だけ作られていく
• インスタンスが露出して外部から使役される懸念が残る
• XHR等で後に挿入されたHTMLへの振る舞いのアタッチが手動
になり、それでまたビジネスロジックが汚染される
後にわかるコードの隙
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
「HTMLとJavaScriptの概念的距離を圧縮したい」
DHH say:
HTMLとJavaScriptはよく見ると、PHPとmysqlみたいな関係にある
セレクタというQueryを投げてDOMを得ている
データアクセスには手続きが必要で、壊れやすく、ビジネスロジックはそ
のコードに埋もれ、さらには独特なそのデータ形式(NodeList等)の
normalizeに苦心する
DOMが変数やプロパティにアクセスするかのように簡単に参照でき、それ
らへのアクセスに制限を設けることができれば問題は軽減する
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
• JavaScriptの中にDOMを記述することでDOMの参照を探索せ
ずに実現している
• これもHTMLとJavaScriptの概念的距離の圧縮に成功し
ている
At modern library
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Use React/Vue?
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
• Existing DOMの安心感はなんだかんだ半端ない
• JavaScriptが最悪動かなくてもHTMLドキュメントとして最低限機能を果たしてくれる
• SEO的な懸念の回避
• インデックスが遅いだけで大丈夫とか、心配ならSSRすればとかあるけどそもそも
そんな不安や複雑性を抱えたくない
• 現行の資産(負債)の大きさ故にシステム構成レベルの変革を望まない
• 負債は一括返済ではなく分割で返済したい
• 返さなくていい負債は返すつもりもない
• カバーする領域がJavaScript領域に閉じてない
• 将来的な別ソリューションの登場時に撤退容易性が低い
• 命預けるなら普遍的なHTMLを軸にしたライブラリにしたい
• 将来的にビルドプロセスをなくしたいのでxxx-loader系と縁を持ちたくない
• ビルド時間を気にしたり、ビルド設定に時間を費やすのはソフトウェアライターとして本
質的ではない
しぶり続けて早5年、理由はよくあるやつ
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
• Existing DOMのアプローチでDOMアクセスを省略できて、インスタンスを隠蔽できて、振る
舞いのアタッチを自動化できたらそれが一番いい
• ついでに流行りのライブラリのようにHTML側からみて振る舞いが宣言的であれば嬉しい
• ブラウザの敷いた道から離れたくない (戻るの大変なので)
• WebComponentsがやや近しい?気がしてそれの発展に期待していた
• 振る舞いの自動アタッチ
• インスタンスの隠蔽
• DOMアクセスの制限(shadow root内に限られる)
わがままな私たち
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
そんなこんなで負債を
垂れ流し続けたある日
Basecamp製のStimulusが熱いゾ
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
• Basecamp製のJavaScriptライブラリ (thx. dhh, sstephenson, javan
• Existing DOMアプローチ
• DOMの変更をMutationObserverで監視し、対象のDOMが出現したら自動で定義した振る舞いをアタッチする。
• 操作したいDOMを明記しておくとgetterメソッドが自動で作られてプロパティのようにアクセスできる
Stimulus
data-[controller]-target=“xxx”
の要素にthis.xxxTargetでアク
セス
data-action=“evt-
>controller#method”で要素に
振る舞いをアタッチ
data-cotrollerでHTMLと
JavaScriptを接続
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
• Existing DOMの絶対的安心感
• アクセスするDOMは事前に定義でき、それらはシームレスにプロパティとしてアクセスできる
• HTML側にアクセスする要素を記述するのでJavaScript側はHTMLの構造変更の影響をほぼ受けない
• 振る舞いは自動でアタッチされインスタンスの隠蔽で悩む必要はない
• HTML側からみて振る舞い、状態が宣言的である
• HTMLの出現時に自動で振る舞いや状態がアタッチされるのでサーバ側からは大きなjsonを返す必要はなくHTMLを返
せばいい
• 必然的に型・スキーマの重要性が下がる
• Primitiveなcontrollerの再利用製の高さ
• DOMをセレクタで探索するのではなくDOM側に対象を明記するのでDOMの構造差異に強く振る舞い自体の再利
用製が高い
• disclosure/remover/modal/content-loader等、再利用製高い単一用途のcontrollerを作ってガンガン再利用できる
Stimulus is great solution
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
• stimulusでHTMLとJavaScriptの概念的距離を縮め、さらには振る舞いを宣言的にする
• 全移行はコストかかるので本気ださない
• 長い期間、既存設計と併用になるがそれを厭わない(困らないので)
• 新しくそこを触るときにstimulusで置き換えられるところをそっと切り出すだけでいい
• Build Processをいつか捨てるという夢は諦めない (ie11が死んだ暁には…)
• bye babel, bye bundler, bye transpiler
• アプリケーションの設定的な複雑性から解放されたい
• PrimitiveなControllerを大量生産してコード量を1/20(次期目標)にしていく
• 新規開発において既存のcontrollerをロードしてhtml側で属性組み立てるだけでそのページの振る舞いが完成すること
が夢
• 書いたコードは例外なく将来負債になる
• コードは書かないに越したことはない
LIFULL HOME’Sの戦略
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
LIFULL HOME’Sの戦略
HTMLを大事に
Webに素直に
Copyright© LIFULL Co.,Ltd. All Rights Reserved.
大きめレガシープロジェクトのフロント行く末
終

大きめレガシープロジェクトのフロント行く末

  • 1.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロン ト行く末 約10年前に作られたLIFULL HOME'Sの現行サイト。負債化したJSは何が不十分で負債化したのか、最小限のコストでよりよい設計・規則を 導入するためにどう立ち向かっていくか 2021.03
  • 2.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 2010年4月入社 アプリケーションエンジニアと入社して10年、現 在はややフロント寄りの業務をしている 学生時代にネトゲで嶌田氏と知り合い、その辺が きっかけでウェブ開発を始めた ウェブとDHHが大好き Nakajima Takuya Twitter: @nazomikan 大きめレガシープロジェクトのフロント行く末
  • 3.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 10年前にリニューアル後、以降大きなリニューアルもなく開発され続けてきたサイト(部分的にマイクロサービス化して いる) アプリケーション側の技術スタック • Symfony2 • Twig • jQuery + Backbone.View的な設計 • Babel/Rollup/Sass/部分的にtypescript LIFULL HOME’Sのサイト内情 1498 files. 136565 lines. JavaScript files (ignore library) おかしいな、さほど大きめではないような…
  • 4.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 基本的にはBackbone.Viewと同じ考え方 テンプレートパーツと対になるJavaScript側のViewがあって、それ単位で 振る舞いを記述している Backbone同様にイベント機構の統一などは重なっている View同士の連携はグローバルなカスタムイベントを使ってやりとりして いた。 (Backbone.Eventsをグローバル放出してpubsubするのとほぼ同じ) 既存コードでのViewの考え方
  • 5.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 • コードの流れの統一 • eventsを見ればそのUIの振る舞いがわかる • 全てのviewでそうなのでリードコストが削減される • Viewごとの振る舞い定義によるファイル分割 (問題あり) 解決されている問題
  • 6.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 結局なくならないDOM探索 • DOM探索で埋漏れるビジネスロジック • セレクタに依存してDOMの変更に弱い • 似た少し違うコードが量産されて、build時間が増大して いく • 横方向の区切りはできても縦方向のviewの境目が守られない • 安易なDOM探索が子,親viewを犯してしまう • 親・子分割がうまく行かず巨大な親だけ作られていく • インスタンスが露出して外部から使役される懸念が残る • XHR等で後に挿入されたHTMLへの振る舞いのアタッチが手動 になり、それでまたビジネスロジックが汚染される 後にわかるコードの隙
  • 7.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved.
  • 8.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 「HTMLとJavaScriptの概念的距離を圧縮したい」 DHH say: HTMLとJavaScriptはよく見ると、PHPとmysqlみたいな関係にある セレクタというQueryを投げてDOMを得ている データアクセスには手続きが必要で、壊れやすく、ビジネスロジックはそ のコードに埋もれ、さらには独特なそのデータ形式(NodeList等)の normalizeに苦心する DOMが変数やプロパティにアクセスするかのように簡単に参照でき、それ らへのアクセスに制限を設けることができれば問題は軽減する
  • 9.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 • JavaScriptの中にDOMを記述することでDOMの参照を探索せ ずに実現している • これもHTMLとJavaScriptの概念的距離の圧縮に成功し ている At modern library
  • 10.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. Use React/Vue?
  • 11.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 • Existing DOMの安心感はなんだかんだ半端ない • JavaScriptが最悪動かなくてもHTMLドキュメントとして最低限機能を果たしてくれる • SEO的な懸念の回避 • インデックスが遅いだけで大丈夫とか、心配ならSSRすればとかあるけどそもそも そんな不安や複雑性を抱えたくない • 現行の資産(負債)の大きさ故にシステム構成レベルの変革を望まない • 負債は一括返済ではなく分割で返済したい • 返さなくていい負債は返すつもりもない • カバーする領域がJavaScript領域に閉じてない • 将来的な別ソリューションの登場時に撤退容易性が低い • 命預けるなら普遍的なHTMLを軸にしたライブラリにしたい • 将来的にビルドプロセスをなくしたいのでxxx-loader系と縁を持ちたくない • ビルド時間を気にしたり、ビルド設定に時間を費やすのはソフトウェアライターとして本 質的ではない しぶり続けて早5年、理由はよくあるやつ
  • 12.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 • Existing DOMのアプローチでDOMアクセスを省略できて、インスタンスを隠蔽できて、振る 舞いのアタッチを自動化できたらそれが一番いい • ついでに流行りのライブラリのようにHTML側からみて振る舞いが宣言的であれば嬉しい • ブラウザの敷いた道から離れたくない (戻るの大変なので) • WebComponentsがやや近しい?気がしてそれの発展に期待していた • 振る舞いの自動アタッチ • インスタンスの隠蔽 • DOMアクセスの制限(shadow root内に限られる) わがままな私たち
  • 13.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. そんなこんなで負債を 垂れ流し続けたある日 Basecamp製のStimulusが熱いゾ
  • 14.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 • Basecamp製のJavaScriptライブラリ (thx. dhh, sstephenson, javan • Existing DOMアプローチ • DOMの変更をMutationObserverで監視し、対象のDOMが出現したら自動で定義した振る舞いをアタッチする。 • 操作したいDOMを明記しておくとgetterメソッドが自動で作られてプロパティのようにアクセスできる Stimulus data-[controller]-target=“xxx” の要素にthis.xxxTargetでアク セス data-action=“evt- >controller#method”で要素に 振る舞いをアタッチ data-cotrollerでHTMLと JavaScriptを接続
  • 15.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved.
  • 16.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 • Existing DOMの絶対的安心感 • アクセスするDOMは事前に定義でき、それらはシームレスにプロパティとしてアクセスできる • HTML側にアクセスする要素を記述するのでJavaScript側はHTMLの構造変更の影響をほぼ受けない • 振る舞いは自動でアタッチされインスタンスの隠蔽で悩む必要はない • HTML側からみて振る舞い、状態が宣言的である • HTMLの出現時に自動で振る舞いや状態がアタッチされるのでサーバ側からは大きなjsonを返す必要はなくHTMLを返 せばいい • 必然的に型・スキーマの重要性が下がる • Primitiveなcontrollerの再利用製の高さ • DOMをセレクタで探索するのではなくDOM側に対象を明記するのでDOMの構造差異に強く振る舞い自体の再利 用製が高い • disclosure/remover/modal/content-loader等、再利用製高い単一用途のcontrollerを作ってガンガン再利用できる Stimulus is great solution
  • 17.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 • stimulusでHTMLとJavaScriptの概念的距離を縮め、さらには振る舞いを宣言的にする • 全移行はコストかかるので本気ださない • 長い期間、既存設計と併用になるがそれを厭わない(困らないので) • 新しくそこを触るときにstimulusで置き換えられるところをそっと切り出すだけでいい • Build Processをいつか捨てるという夢は諦めない (ie11が死んだ暁には…) • bye babel, bye bundler, bye transpiler • アプリケーションの設定的な複雑性から解放されたい • PrimitiveなControllerを大量生産してコード量を1/20(次期目標)にしていく • 新規開発において既存のcontrollerをロードしてhtml側で属性組み立てるだけでそのページの振る舞いが完成すること が夢 • 書いたコードは例外なく将来負債になる • コードは書かないに越したことはない LIFULL HOME’Sの戦略
  • 18.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 LIFULL HOME’Sの戦略 HTMLを大事に Webに素直に
  • 19.
    Copyright© LIFULL Co.,Ltd.All Rights Reserved. 大きめレガシープロジェクトのフロント行く末 終