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
RemixでWeb標準を学んだ1年間 / First year with Remix
Search
Yukiya Nakagawa
January 23, 2024
Technology
23
8.1k
RemixでWeb標準を学んだ1年間 / First year with Remix
フロントエンドの技術選定 ~2023を振り返る~ Lunch LT での発表資料です
https://findy.connpass.com/event/306714/
Yukiya Nakagawa
January 23, 2024
Tweet
Share
More Decks by Yukiya Nakagawa
See All by Yukiya Nakagawa
Remix × Cloudflare Pages × Sentry 奮闘記 / remix-pages-sentry
nkzn
1
880
Cloudflareスタックで月間1200万UUの経済メディアにアバター画像生成サービスを作る / Cloudflare Developer Platform for AI avatar service
nkzn
7
2.7k
5分で流し読むCloudflare Developer Platform
nkzn
3
280
次世代Web認証「パスキー」 / mo-zatsudan-passkey
nkzn
31
18k
パスキーについて今日時点の僕が知っていること / What I Know About Passkeys as of Today
nkzn
8
2.7k
青い空の歩き方 / Flying in the bluesky
nkzn
1
260
SPAの歴史とRemix SPAモードという到達点 / the SPA's chronicle reaches to remix
nkzn
47
17k
純粋培養フルリモート開発組織のワーク&ライフスタイル / monicle full remote style
nkzn
5
3.8k
資産運用を対面で相談するサービスでITエンジニアがやることあるの? / derta-gig-04
nkzn
0
1.4k
Other Decks in Technology
See All in Technology
フロントエンド設計にモブ設計を導入してみた / 20241212_cloudsign_TechFrontMeetup
bengo4com
0
1.9k
統計データで2024年の クラウド・インフラ動向を眺める
ysknsid25
2
840
Fanstaの1年を大解剖! 一人SREはどこまでできるのか!?
syossan27
2
170
多領域インシデントマネジメントへの挑戦:ハードウェアとソフトウェアの融合が生む課題/Challenge to multidisciplinary incident management: Issues created by the fusion of hardware and software
bitkey
PRO
2
100
組織に自動テストを書く文化を根付かせる戦略(2024冬版) / Building Automated Test Culture 2024 Winter Edition
twada
PRO
13
3.7k
サイバー攻撃を想定したセキュリティガイドライン 策定とASM及びCNAPPの活用方法
syoshie
3
1.3k
alecthomas/kong はいいぞ / kamakura.go#7
fujiwara3
1
300
日本版とグローバル版のモバイルアプリ統合の開発の裏側と今後の展望
miichan
1
130
Storage Browser for Amazon S3
miu_crescent
1
140
.NET 9 のパフォーマンス改善
nenonaninu
0
900
開発生産性向上! 育成を「改善」と捉えるエンジニア育成戦略
shoota
2
350
re:Invent をおうちで楽しんでみた ~CloudWatch のオブザーバビリティ機能がスゴい!/ Enjoyed AWS re:Invent from Home and CloudWatch Observability Feature is Amazing!
yuj1osm
0
120
Featured
See All Featured
Large-scale JavaScript Application Architecture
addyosmani
510
110k
Automating Front-end Workflow
addyosmani
1366
200k
Writing Fast Ruby
sferik
628
61k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
132
33k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.1k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.3k
Building Your Own Lightsaber
phodgson
103
6.1k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
95
17k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Java REST API Framework Comparison - PWX 2021
mraible
28
8.3k
Keith and Marios Guide to Fast Websites
keithpitt
410
22k
Transcript
Remix💿でWeb標準を学んだ1年間 フロントエンドの技術選定 〜2023を振り返る〜 Lunch LT Yukiya Nakagawa a.k.a Nkzn 0:00
We are hiring! • ソフトウェアエンジニアを積極採用中です! • カジュアル面談お待ちしてます → @NkznにDMください •
求人情報はこちら Findy HRMOS monicle.co.jp
自己紹介 • 中川幸哉 a.k.a Nkzn(なかざん) • ‘86世代🐰の36歳(来月37になります) • 新潟生まれ新潟育ち •
8歳と4歳の父で妻の夫 • 2011〜2021年は農業IT🌾の人 • 2021年から株式会社モニクル ◦ 資産運用お手伝いサービス「マネイロ」のIT裏方 0:05
https://speakerdeck.com/monicle/culture-deck 0:20
どんなプロダクトに Remix💿を採用したのか 0:35
https://speakerdeck.com/monicle/culture-deck 前月の収益を 毎月上旬に 自動で集計したい! 0:50
どんなプロダクトに採用したのか • 社内向けの収益計算システム(会計システムのサブシステム) • フロントエンド用のフレームワークとして採用 ◦ DB操作やお金の計算はバックエンドサーバーに任せる • APIキャッシュはいらない ◦
少数の社員しか触らない&管理システムとしての側面が強い ◦ 常に最新の情報がAPIサーバーから出てきて表示できればよい • 権限管理は結構重めで、監査法人が目を光らせている ◦ 上場のために作ってるシステムなので仕方ないね 1:05
なぜRemix💿を採用したのか 1:20
選定時期 • 2022年夏〜秋ごろ • Remixはv1.7.1くらい • Why NOT App Router
◦ Next.js v13.0は2022年10月末リリースでした ◦ 物理的に選択肢に上らない時期だった 1:35
開発メンバーの想定スキル • メイン事業のひとつ https://moneiro.jp はNext.js製 ◦ 開発組織全体としては基本的にNext.jsを選びがち ◦ Pages Routerの世界観には慣れている人が多い
◦ 新規開発ではApp Routerも採用はしている • TypeScriptとReactは書ける • File-system based routerも馴染み深い • Next.js経由でレイアウト的な考え方も知ってた へっだー さいどばー ここだけ 画面遷移する レイアウト的なやつ 1:50
プロダクトの要件・特性 • 社内のSFA内にある契約データを収益データにコンバートするやつ • ユーザー数は数名 • ビジネスロジックやデータベース操作はバックエンドサーバーに任 せて、別のクライアントと繋ぐ余地を残したい • フロントエンドのフレームワークはなんでもいいといえばなんでも
いい • 強いて言えば、常に最新の情報を表示したいので、キャッシュ機構 はあってもあんまり使わない 2:05
Remix💿にした要因 • Next.jsへの逆張り • 通信と画面遷移が統合されたフ レームワーク • 学習コストを効率的に使えそう ◦ Web標準のパーツをフレーム
ワークに組み込んでいる • スイッチングコストを減らせそう ◦ サーバーサイドのコードもブ ラウザっぽく書ける • フレームワークとしてはキャッ シュ機構がなく、HTTP Headerを 扱いやすくすることで対応してい る • React Routerベース ◦ ちょくちょく使ってきたので 土地勘がある ◦ 割としんどいBreaking Changeやりがち問題 2:20
v1のPhilosophyに惚れてしまった • https://remix.run/docs/en/1.19.3/pages/philosophy • Web標準には結構いいパーツが揃ってきているので活用することに したし、フレームワークによる隠蔽・抽象化も最小限にする ◦ ex. 通信周りはlib.dom.d.tsの型定義をそのまま使うことが多い •
せっかく学習コストを払うならWeb標準を学んだほうが潰しが効く – Get good at Remix, get good at the web. v2にはエモ文書置き場がないのでなくなっちゃった 😢 2:35
3分でわかるRemix 開発 2:50
export async function loader() { // データ読み込み( GraphQL Query) }
export default function Component() { const loaderData = useLoaderData<typeof loader>(); const actionData = useActionData<typeof action>(); // このルートに表示したい UIを定義する } export async function action() { // データを更新する( GraphQL Mutation) } Route app/routes/ 内の1ファイル 3:05
export async function loader({ request, // Fetch APIのRequest params, }:
LoaderFunctionArgs) { const { id } = params; const user = await getUser(request, id); // Fetch APIのResponse return new Response(JSON.stringify({ displayName: user.displayName, email: user.email, }), { headers: { "Content-Type": "application/json; charset=utf-8", }, }); } Loader データ取得関数 このroute用GET専門エンド ポイントみたいなイメージ 3:20
export async function loader({ request, // Fetch APIのRequest params, }:
LoaderFunctionArgs) { const { id } = params; const user = await getUser(request, id); return json({ displayName: user.displayName, email: user.email, }); } Loader Responseの薄いラッパー `json()` 3:35
Action export async function action({ request, }: ActionFunctionArgs) { //
Requestオブジェクトからフォームデータを取得する const body = await request.formData(); const name = body.get("visitorsName"); return json({ message: `Hello, ${name}` }); } export default function Component() { const data = useActionData<typeof action>(); return ( <Form method="post"> <input type="text" name="visitorsName" /> {data ? data.message : "Waiting..."} </Form> ); } loaderと同じインター フェース フォームリクエスト受付専 用関数 3:50
Fullstack Data Flow https://remix.run/docs/en/2.5.1/discussion/data-flow 4:05
File-system based routing app/ ├── routes/ │ ├── _index.tsx │
├── about.tsx │ ├── concerts._index.tsx │ ├── concerts.$city.tsx │ ├── concerts.trending.tsx │ └── concerts.tsx └── root.tsx Next.jsと大体一緒! と言いたかったけど、v2で ドット区切りになりました /concerts/* のレイアウト /concerts /concerts/$city /concerts/trending / /about 4:20
認証はremix-authでなんとかしてる • Remixにはセッション情報管理の仕組みが標準で組み込まれている ◦ https://remix.run/docs/en/main/utils/sessions ◦ まずはCookieに保存して、4KB制限を超えそうになったらKVSに移行すると かでもいいかも • 認証フローの管理が得意なremix-authを併用すると便利
◦ https://github.com/sergiodxa/remix-auth • 社内標準のIdPがMicrosoft Entra ID(旧Azure AD)なので、 remix-auth-oauth2をベースにOAuth2の認証フローを組んである ◦ https://github.com/sergiodxa/remix-auth-oauth2 ◦ (参考)https://github.com/juhanakristian/remix-auth-microsoft 4:35
Remix💿を学んで Web標準(というかHTML) に再入門した事例 4:50
テーブルで1行1フォームを作りたい 5:05
私たちのフォーム周り事情 in Remix💿 • 基本は古き良き `<form>` で、実際にはSPA的な動作をサポートするため に薄くラップした `<Form>` を使う
• フォーム管理にはremix-validated-formを使っている ◦ https://www.remix-validated-form.io/ ◦ Zodで書いたスキーマをバリデーションに利用するためのアダプ ター • 非制御コンポーネント縛りで頑張ることにしている ◦ JavaScriptのロードが完了する前からユーザーが触れたほうが Remixっぽい 5:20
the 愚直 <tr> <Form action="post"> <td> <input type="hidden" id="id" name="id"
value="1111" /> </td> <td>2023-11-23</td> <td><input type="text" id="a" name="a" /></td> <td><input type="text" id="b" name="b" /></td> <td><input type="text" id="c" name="c" /></td> <td><input type="button" value="送信" /></td> </Form> </tr> tr > form > td > input 5:35
InvalidなHTMLとしてバチクソ怒られた (それはそう) 5:50
HTMLど素人ワイ、StackOverflowで救いを得る https://stackoverflow.com/questions/1249688/html-is-it-possible-to-have-a-form-tag-in-each-table-row-in-a-xhtml-valid-way 6:05
form属性を使う <tr> <td> <form id="form1" action="post"> <input type="hidden" id="id" name="id"
value="1111" /> </form> </td> <td>2023-11-23</td> <td><input form="form1" type="text" id="a" name="a" /></td> <td><input form="form1" type="text" id="b" name="b" /></td> <td><input form="form1" type="text" id="c" name="c" /></td> <td><input form="form1" type="button" value="送信" /></td> </tr> tr > td > form#form1 > input[form=”form1”] tdの中にある分には valid扱い form要素のid属性に指定した値を input要素のform属性に指定すると form要素の外側にある input要素も紐付けられる 6:20
We got Kotonaki. 6:35
改めて見てみる https://stackoverflow.com/questions/1249688/html-is-it-possible-to-have-a-form-tag-in-each-table-row-in-a-xhtml-valid-way 6:50
HTMLど素人ワイ、 15年前(2009)に質問されて 10年前(2014)に回答された StackOverflowに救われる 7:05
恥の多い人生を送ってきました • どこかWeb標準を軽視していた自分に気付かされる機会が増えた • Remixで開発していると、Web標準を学ぶ機会が多く得られる • MDNを参照する頻度が増えるごとに、RemixやReactが死んでも使 えるスキルが手元に残る • ありがとうRemix、ありがとうWeb標準、これからもよろしく
7:20
1年間やってきて • 通信周りの非同期処理について頭を悩ませる頻度が激減した • よりプロダクトが事業に与えるバリューについて考える時間が増え た • 昔よりもMDNと仲良くなった気がする • Remixは愚直で退屈なフレームワークなのかもしれない
• 僕はフレームワークよりプロダクト、プロダクトより事業そのもの にエキサイトしたいので、フレームワークは退屈でもいい • Remix、一度お試しください 7:35
おまけ Remix💿のバージョンアップ事情 (時間がなければ割愛します) 7:50
React Router被害者の会 • RemixのコアライブラリでもあるReact Routerは、アップグレード 体制がちょっと悪名高かった • 特にv3→v4でごっそり変わって、結局追従できなかったという人も https://twitter.com/mizchi/status/856797318930026497 8:05
Remixでどうなったの • 2023年9月にv2が出たので振り返ってみる ◦ https://remix.run/blog/remix-v2 • 大きめのBreaking Changeはあったがフォローが手厚かった印象 8:20
内容自体は大小色々あった • アップグレードガイドを見てもらうとわかるけど、変更自体はめ ちゃくちゃあった ◦ https://remix.run/docs/en/2.5.1/start/v2 • これをビッグバンリリースしていたら、たぶんみんなブチ切れてい たと思う •
実際にはそうならないための手厚い配慮が行われた 8:35
Remix💿 future flag /** @type {import('@remix-run/dev').AppConfig} */ module.exports = {
future: { v2_meta: true, // since 2022.12 v2_errorBoundary: true, // since 2023.04 v2_normalizeFormMethod: true, // since 2023.04 v2_routeConvention: false, // since 2023.04 v2_headers: true, // since 2023.06 v2_dev: false, // since 2023.06 }, }; v1 → v2 8:50
future flagの導入 • Vueのv2→v3のアップグレードの際のfeature flagの使い方にインスパイアされ た、future flagというものを用いて、穏便にアップグレードを進める作戦が採ら れた ◦ https://remix.run/blog/future-flags
• v1.xの内に内部的にv2版のモジュールがオプトインでリリースされており、 remix.config.jsでフラグを切り替えることで、特定の機能のみをv2版で動作させ ることができた • 一つ一つのアップグレードについては、全くトラブルがなかったとは言えないも のの、重たいものについてはv2のstableリリースまで、約半年の対応期間が与え られたことになる 9:05
Shopify買収の影響かも • メジャーバージョンもう1回分くらいは注視してもいいかもしれな いけど、ひとまず今回は慎重だったように見えた • 2022年10月にShopifyに買収されたのが良い影響になったのかも ◦ https://remix.run/blog/remixing-shopify • ShopifyのECサイト自作用SDK、HydrogenがRemixベースになった
• あんまりにも非互換なアップグレードをしてしまうと、普通に ShopifyのB2B事業の顧客に迷惑がかかるので、迂闊にビッグバンリ リースできなくなったのでは 9:20
Shopifyは堅実に進めていくイメージ • 以前、Shopifyアプリの内部実装を徐々にReact Nativeに置き換え ていくプロジェクトがあったりした ◦ https://shopify.engineering/migrating-our-largest-mobile- app-to-react-native • 顧客へ悪影響が出やすいビッグバンリリースは避け、たとえ技術的
に困難な道になろうと漸進的に進めていく文化があるように感じた • Remixもそんな感じで進めていってほしい(期待) 9:35
完 9:50
We are hiring! • ソフトウェアエンジニアを積極採用中です! • カジュアル面談お待ちしてます → @NkznにDMください •
求人情報はこちら Findy HRMOS monicle.co.jp 10:00