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
てけし
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
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.1k
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
180
すこし踏み込む CancellationToken
htkym
2
1.5k
Turning Architecture into Unit Tests in the AI Era (NSSpain XIV)
steliosf
PRO
1
120
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
460
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
150
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
270
Are APIs Still Relevant in the AI Era?
soyuka
0
380
SREの越境 / SRE Collaboration
y0hgi
2
290
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
320
選挙速報を多くのユーザーへ 届ける Live Activities 設計
hamayokokuririn
0
190
Featured
See All Featured
Automating Front-end Workflow
addyosmani
1369
210k
Tell your own story through comics
letsgokoyo
1
1.1k
KATA
mclloyd
PRO
35
16k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
Test your architecture with Archunit
thirion
2
2.4k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
320
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
550
For a Future-Friendly Web
brad_frost
183
10k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
390
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
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 参考記事