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
RTSPクライアントを自作してみた話
simotin13
0
620
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
580
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
350k
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
170
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
600
Performance Engineering for Everyone
elenatanasoiu
0
200
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
560
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
2
250
Contextとはなにか
chiroruxx
1
360
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
360
Inside Stream API
skrb
1
760
Featured
See All Featured
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.6k
Become a Pro
speakerdeck
PRO
31
6k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
210
Building Applications with DynamoDB
mza
96
7.1k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
390
First, design no harm
axbom
PRO
2
1.2k
How to train your dragon (web standard)
notwaldorf
97
6.7k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
440
We Have a Design System, Now What?
morganepeng
55
8.2k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
200
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 参考記事