Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
フロントエンドで 良いコードを書くために
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
てけし
January 18, 2023
Programming
2.5k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
フロントエンドで 良いコードを書くために
フロントエンドLT新年会の資料
https://thecoo.connpass.com/event/269188/
てけし
January 18, 2023
More Decks by てけし
See All by てけし
eslint-flat-config
t_keshi
5
1.1k
Other Decks in Programming
See All in Programming
自動化したのに回らない テスト運用の壁―AI時代の品質責任と生産性
mfunaki
0
560
AIに既存システムを理解させる技術 ~レガシーを見捨てないハーネスエンジニアリング入門~
ochtum
0
180
業務時間外もAIに働いてもらう話
colorful12
3
9.5k
DynamoDBの基礎を振り返りながらベクトル検索機能を理解する
musan
3
260
リアルな遅延を測る仕様
kota_yata
1
130
Can LLMs Replicate 4 Years of Compose Migration? Exploring the boundaries of automation with 279 XML files from a real product
makun
0
110
Go を使い始めて 2 ヶ月の学び / My first two months with Go
contour_gara
0
400
AI時代に学ぶ 好きなルール 嫌いなルール Linter編
shorty5121
0
700
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
500
Gmail/Google DriveをトリガーにAIエージェントを動かそう! / Run AI agents with Gmail/Google Drive as triggers!
har1101
3
460
My Marp Sample
sinoue0108
0
140
in-process GraphQL のすすめ #ginzajs
izumin5210
4
1.5k
Featured
See All Featured
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
570
BBQ
matthewcrist
89
10k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
760
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
300
The browser strikes back
jonoalderson
0
1.6k
Darren the Foodie - Storyboard
khoart
PRO
3
3.8k
Utilizing Notion as your number one productivity tool
mfonobong
4
560
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
430
Chasing Engaging Ingredients in Design
codingconduct
0
290
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Transcript
フロントエンドで 良いコードを書くために Sansan株式会社 技術本部 Strategic Products Engineering Unit Contract One
Devグループ 井上丈士
写真が入ります 井上丈士 Sansan株式会社 技術本部 Strategic Products Engineering Unit Contract One
Devグループ zenn: t-keshi twitter: t__keshi 趣味: サウナ駆動技術記事投稿
(我々は常に思い悩む) どうしたら良いコードが 書けるようになるだろうか...?🤔
知識や経験...?🤔 いや、もう少し具体化しないと コードを良くする方法が見えてこない
良いコードを書くための方法を、 以下のように分類・整理することはできないだろうか? そこで、、、 設計原則 フレーム ワークの知識 対話
①狭義の設計原則 設計原則
設計原則と聞いて、まず頭に浮かぶもののこと。 オニオンアーキテクチャや クリーンアーキテクチャのようなものが挙げられる。 「フロントエンドのクリーンアーキテクチャ」 一時期、流行った、バックエンドのアーキテクチャを輸入する方針 狭義の設計原則
設計原則の輸入の問題点
オニオンインオニオンを良しとする意見もある。 しかし、0コストで変更容易性が得られるわけではない。 可読性・複雑さとのトレードオフ。 その割に、フロントエンドはフレームワークへの依存が大きく、 どう足掻いても変更はそれほど容易にならない。 オニオンインオニオンの何が駄目か?
実装パターンとその背後にある考え方は、区別した方が良さそう。 実装パターンとその背後にある考え方 背後にある考え方 BE実装パターン FE実装パターン
例えば責務を意識したレイヤー分け ❌悪い例 データ取得の責務 getUsers()などに切り出すべき 表示の責務 その背後にある考え方? const UsersPage = ()
=> { const [user, setUsers] = useState(null) useEffect(() => { const asyncFn = async () => { const response = axios.get("https://hoge-api/users", { headers: {...省略...} }) return response.data } asyncFn() }, []) return <UsersTable users={users} /> }
いわゆるリーダブルコード的なもの。 設計原則に含めていいのか微妙だが、 設計本には、こうした内容も書いてある。 ex.)良いコード悪いコードで学ぶ設計入門 基本的には本の内容をFEにもそのまま適用可能。 JavaScript/TypeScriptでリーダブルなコードを考えるなら、 どんなことが言えるだろうか? 広義の設計原則
静的に分岐漏れを検出する。 条件分岐のコツ1 TypeScript 4.9以降 type Action = | { type:
"OPEN"; payload: { message: string } } | { type: "CLOSE" } | { type: "TOGGLE" } const reducer = (action: Action) => { switch (action.type) { case "OPEN": return { isOpen: true, message: action.payload.message } case "CLOSE": return { isOpen: false, message: null } default: // TOGGLEがないのでコンパイルエラー throw new Error(action satisfies never) } } TypeScript 4.9以前 type Action = | { type: "OPEN"; payload: { message: string } } | { type: "CLOSE" } | { type: "TOGGLE" } const reducer = (action: Action) => { switch (action.type) { case "OPEN": return { isOpen: true, message: action.payload.message } case "CLOSE": return { isOpen: false, message: null } default: // TOGGLEがないのでコンパイルエラー throw new Error((action as { type: "__invalid__" }).type) } }
処理の分岐というより、単純な対応を表す場合は、 Switchの代わりにObjectを使う。 条件分岐のコツ2 type Status = "active" | "inactive" |
"sleep" const UserStatus = (status: Status) => { const icon = { active: <ActiveIcon />, inactive: <InactiveIcon />, sleep: <SleepIcon /> }[status] return <div>{icon}</div> }
RoRoとは、”Receive an Object, Return an Object” オブジェクトで受けてオブジェクトで返すこと RoRo const createUser
= (userId: string, userAccountId: string) => { // 省略 } const UserRegistrationDialog = () => { const handleSubmit = (userAccountId: string, userId: string) => { // 引数を渡し間違える createUser(userAccountId, userId) } return <Dialog onSubmit={handleSubmit}/> } Objectを使うと混乱は防げる (他の言語でいう名前付き引数やキーワード引数) const handleSubmit = ({userId, userAccountId}) => { createUser({ userId, userAccountId}) }
Gap
②フレームワークの知識
あまりにもuseEffectが乱用されすぎている。 これはありがちな悲劇。 useEffectはエスケープハッチ、仕方なく使うもの。 useMemoなどで済むようなケースで、 安易にuseEffectを使ってはいけない。 例えばReactだと1
余計なFragmentが多すぎる。 些細な問題だが、多発すると可読性を下げる要因に。 nullもstringもnumberも 立派なReactElementであり、FCのReturnType。 例えばReactだと2
無闇にStateに入れまくる。 状態管理はシンプルに保つのがキモ。 ❌悪い例 例えばReactだと3 const HogeComponent = () => {
const [users, setUsers] = useState() const [admin, setAdmin] = useState() // その他数多くのStateなど, 500行くらい return <div /> // ようやくJSX }
(再掲)フロントエンドにはフロントエンドの実装パターンがある。 では、フロントエンドの実装パターンとは何だろう? それは、ある程度、フレームワーク依存になってしまう。 Reactの場合だと、 <CustomHook>と<コンポーネント設計> なのではないかと思う。 フレームワークの実装パターン
APIの呼び出しはsetLoadingやsetErrorなどのボイラプレートに溢れる これは特にCustomHookを使うべきところ react-useのCustomHookを参考にするのもおすすめ 込み入ったロジックはどんどんCustomHookに切り出していこう CustomHook const HogeComponent = () =>
{ const [state, setState] = useState() …500行くらいあるコード... return ようやくJSX } CustomHookで切り出そう
taroさんのLTに続く コンポーネント設計
Last Journey
③対話
コンポーネント、それが一番大事 - 基盤となるUIコンポーネントが不足していると、開発速度が出ない - 良いコンポーネントは、開発のアクセル そして、そんなコンポーネントを作るために必要なのが、
デザインチームとの対話
ビジネスサイドとの対話 - ビジネスサイド、開発サイドの相互理解 - いつもそれがうまくいくとは限らないが、チーム全体としてのたしかな進歩につな がる
まとめ
対話 フレームワークの知識 設計原則 良いコード
「なぜ良いコードが書けないんだろう」 悩んだときは、それを各要素に分解し、 各個撃破していくことが大事。 ぼんやりした問題を具体的な要素に分解することさえできれば、 「悩む」のではなく、「考える」ことができる。 今日はそんな話がしたかった。
採用情報はこちら https://media.sansan-engineering.com/ 積極採用中!!
ありがとうございました!
狭義の設計原則 WebフロントエンドでDDDを導入のメリットってあるでしょうか WEBフロントエンドにおけるソフトウェア設計の考察 広義の設計原則 Elegant Patterns in Modern JavaScript フレームワークの基礎知識
You Might Not Need an Effect 参考記事