Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
フロントエンドで 良いコードを書くために
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
てけし
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
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
1.2k
Compiling a real-world CLI tool to native with Static Hermes
tmikov2023
0
130
ActionController meets Protocol Buffers
sorah
0
680
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
300
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
1.1k
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
6.9k
オーケストレーション記述言語 Katari
yukikurage
0
190
Rでドレミ/Do-Re-Mi_with_R
florets1
0
130
AI-Powered Domain-Driven Design
ziobrando
0
260
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
조합이폭발하는디자인시스템이걸눈으로도테스트하라고요
giljongyu
0
310
コーディング自動化の次へ。人の介入をゼロにするファクトリーとサポートAIによる実践
timakin
5
4.4k
Featured
See All Featured
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
310
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
490
How to Ace a Technical Interview
jacobian
280
24k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
760
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
580
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
580
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Code Reviewing Like a Champion
maltzj
529
40k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.9k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
How STYLIGHT went responsive
nonsquared
100
6.3k
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 参考記事