Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Next.js App Router

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Next.js App Router

Avatar for Yosuke Kurami

Yosuke Kurami

April 30, 2024
Tweet

More Decks by Yosuke Kurami

Other Decks in Programming

Transcript

  1. About me - id: @Quramy (GitHub, X) - ॴଐ: גࣜձࣾϦΫϧʔτ

    
 (ΞϓϦέʔγϣϯιϦϡʔγϣϯ G) - ৬छ: ϑϩϯτΤϯυΤϯδχΞ
  2. Next.js App Router is Կ - Next.js ʹ͓͚Δ৽͍͠ΞϓϦέʔγϣϯ։ൃελΠϧͷ͜ͱ - ඪ४Ͱ

    React Server Components (ҎԼ RSC) ٴͼ Server Actions (ҎԼ SA) ͕ར༻Մೳ
  3. App Router ࠾༻ʹࢸͬͨഎܠ - ର৅Ҋ݅: ݁ࠗྖҬ(θΫγΟΛ΍͍ͬͯΔͱ͜Ζ) ʹ͓͚Δ৽نࣄۀ - ಉྖҬͷଞϓϩμΫτͰ͸ Next.js

    Pages Router Λ࢖ͬͨ։ൃΛߦͬ ͍ͯΔͨΊɺApp Router ͷ࢖͍৺஍Λຯݟͯ͠Έ͍ͨ 
 → Quramy ΋Ұຕט·ͤͯ΋Β͏͜ͱʹ - ։ൃظؒ: 2023.6݄ - 2023.12݄ - ϑϩϯτΤϯυن໛: ໿40ϖʔδ, 180 Component
  4. App Router ʹର͢Δॴײ 2023.6 ʙ 2023.12 ·Ͱͷ໿̒ϲ݄ؒͷ։ൃظؒΛ௨ͨ͡ App Router ʹର

    ͢Δॴײ - ϙδςΟϒ: - Data Fetching ؔ࿈ʹ͍ͭͯɺैདྷΑΓ΋௚ײతͳ࣮૷͕ՄೳͰ͋Δɻ 
 ʮBFF ͷͨΊͷ API ΤϯυϙΠϯτʯͳͲͷதؒ੒Ռ෺ʹ͔͔Δઃ ܭɾ࣮૷ίετ͕࡟ݮ͞ΕΔ - νϡʔχϯάΛߦ͍ͬͯͳ͍ঢ়ଶͰ΋ɺे෼ʹߴ଎ͳΞϓϦέʔγϣ ϯΛߏஙͰ͖ͨ
  5. App Router ʹର͢Δॴײ 2023.6 ʙ 2023.12 ·Ͱͷ໿̒ϲ݄ؒͷ։ൃظؒΛ௨ͨ͡ App Router ʹର

    ͢Δॴײ - ωΨςΟϒ: - पลΤίγεςϜ(e.g. Styling, UI Lib, Form lib, ςετ) ͕ RSC ʹ௥͍ ͍͍ͭͯͳ͍ - ͱ͸͍͑χʔζ͸͋ΔͷͰɺ͕࣌ؒղܾ͍ͯ͘͠ྨͷ࿩ͱࢥ͏
  6. શମతͳΞʔΩςΫνϟ CloudFront EKS Cluster k8s namespace Frontend SVC Backend API

    SVC RDS Next.js Spring Boot AWS Cloud - Πϯϑϥ: AWS (EKS) - Backend API: Spring Boot - Frontend: Next.js (ϝΠϯϢʔεέʔε͸ SSR) 

  7. ϑϩϯτΤϯυελοΫ ओͳ Dependencies Data Fetching RSC / Server Actions HTTP

    Client WHATWG Fetch (undichi) API Client Open API Generator ελΠϦϯά (CSS) CSS Modules UI ϥΠϒϥϦ - UI State Management jotai Form ϥΠϒϥϦ - Scaffolding hygen Component Χλϩά @storybook/react Unit Testing Jest Component Testing Jest + RTL E2E Testing Playwright
  8. ϑϩϯτΤϯυελοΫ Data Fetching App Router ͷ࠾༻͸ Data Fetching ʹ RSC

    / SA Λ༻͍Δ͜ͱΛҙຯ͍ͯ͠ Δ(ٯʹ͜ΕΒΛ࢖Θͳ͍ͷͰ͋Ε͹ɺٕज़ݕূͷҙຯ͕ബΕͯ͠·͏) - ʮσʔλΛදࣔ͢ΔʯʮσʔλΛߋ৽͢ΔʯͷͲͪΒͰ͋ͬͯ΋ɺSC / SA Ͱ׬݁͢Δ - SWR ΍ tRPCɺApollo Client ͷΑ͏ͳ Data Fetch ϥΠϒϥϦΛෆཁͱͰ ͖ΔͨΊɺඪ४Խָ͕ - SC / SA ͱ΋ʹʮReact ͷ࢖͍ํʯͷ࿩Ͱ͔͠ͳ͍ɻԾʹ Next.js Ͱͳ ͔ͬͨͱͯ͠΋Ԡ༻ͷޮ͘஌ࣝͱͳΔ͸ͣ
  9. ϑϩϯτΤϯυελοΫ ελΠϦϯά(CSS) Runtime CSS in JS ܥ͕ݢฒΈ RSC Ͱಈ࡞͠ͳ͍ͨΊɺݕ౼࣌఺(2023.6݄) Ͱ࠷΋ރΕ͍ͯͨ

    CSS Modules Λ࠾༻ - ΋͍͠·બ୒͢ΔͷͰ͋Ε͹ Zero Runtime CSS in JS Λ΋͏গ͠ݕ౼͠ ͍͔ͯͨ΋ - ϏϧυπʔϧνΣʔϯ͕ա౉ظͰ͋Δ͜ͱΛߟ͑Δͱ PandaCSS ͷΑ͏ ͳɺτϥϯεύΠϧʹ৵ऻ͠ͳ͍Ξϓϩʔνͷ΋ͷΛબͼ͍ͨ
  10. ϑϩϯτΤϯυελοΫ UI State Management State management ʹ jotai Λ࠾༻ -

    RSC Ͱ͸খཱࣗ͘͞෼ࢄͳ CC ಉ͕࢜૬ޓʹ࿈ܞ͢ΔੈքʹͳΔͷͰ͸ʁ 
 ͱ͍͏༧ײ͕͋ͬͨ - ྫ: Component X ͕ Viewport ʹަࠩ࣌ɺ Component A ͷදࣔঢ়ଶ͕มԽ - Pages Router ͷ৔߹ɺX ͱ A ྆ํΛؚΜͩҰݸͷComponent ͱͯ͠ه ड़͍ͯͨ͠Γ͢Δ => useState ͚ͩͰԿͱ͔ͯ͠͠·͏͜ͱ΋Ͱ͖ͨ - App Router Ͱ X / A ͕ CC ͱͯ͠෼ࢄ഑ஔ͞ΕΔͱɺͦ͏͸͍͔ͳ͘ͳΔ ͷͰ͸?
  11. Page Component Component A ෦෼ Component X ෦෼ const [hoge,

    setHoge] = useState(true) hoge Λࢀর setHoge Λࢀর Page Component (Async SC) Component A (CC) Component X (CC) hoge Λࢀর hoge Λߋ৽ ͜ͷ component Λ SC ʹ͢ΔͷͰ͋Ε͹ Hooks ͸ར༻Ͱ͖ͳ͍ State ͢΂͕ͯ CC ͷੈք SC / CC Λؾʹ͢Δੈք ※ ͨͩͷσʔλදࣔ෦෼ ※ ͨͩͷσʔλදࣔ෦෼ (SC) ϑϩϯτΤϯυελοΫ UI State Management
  12. ϑϩϯτΤϯυελοΫ UI State Management - jotai + Next.js Λ࢖͏্Ͱͷॾ஫ҙ: -

    SSR ࣌ʹ atomFamily ͕ϝϞϦϦʔΫ͢ΔͨΊɺ͓૟আ͕ඞཁ 
 https://jotai.org/docs/utilities/family#caveat-memory-leaks import { type Atom } from 'jotai' import { atomFamily as atomFamilyiDelegate } from 'jotai/utils' export function atomFamily<Param, AtomType extends Atom<unknown>>( initializeAtom: (param: Param) => AtomType, areEqual?: (a: Param, b: Param) => boolean, ) { const delegate = atomFamilyiDelegate<Param, AtomType>(initializeAtom, areEqual) return new Proxy(delegate, { apply: (createAtom, _, [param]: [Param]) => { if (typeof document !== 'undefined') { return createAtom(param) } const atomItem = createAtom(param) queueMicrotask(() => createAtom.remove(param)) return atomItem }, }) }
  13. ϑϩϯτΤϯυελοΫ ͦͷଞ Կ΋࠾༻͠ͳ͔ͬͨܥ౷ - Form ϥΠϒϥϦ - ͍ΘΏΔ react-hook-form ͳͲͷܥ౷

    
 ը໘ೖྗཁ͕݅ϥδΦϘλϯ/νΣοΫϘοΫεͷΈɻͦ΋ͦ΋ϥΠϒϥϦ͕ෆཁͳ ϨϕϧͩͬͨΊ - UI Component ϥΠϒϥϦ - બఆ͍ͯ͠Δ༨༟͕ͳ͔ͬͨͱ͍͏ফۃతͳཧ༝ 
 RSC ͱ૬ੑͷྑ͍ UI Component ϥΠϒϥϦ͕͋Ε͹஌Γ͍ͨͰ͢ʂ
  14. ύϑΥʔϚϯε/Ωϟογϡઓུ ͳͥ Next.js ͷ Cache Λར༻͍ͯ͠ͳ͍͔: - ΞϓϦέʔγϣϯಛੑ্ɺData / Full

    Route Cache ʹର͢Δ hit rate ͕ߴ͘ͳΒͳ͍͜ͱ ͕Θ͔͓ͬͯΓɺΩϟογϡΛؤுΔࢫຯ͕গͳ͔ͬͨ - EKS Pod ؒͰ Cache Λڞ༗͢Δ࢓૊Έʹ͍ͭͯະݕ౼ - σϑΥϧτͰ͸ Data Cache, Full Route Cache ͸ϑΝΠϧγεςϜ্ʹӬଓԽ͞Ε Δɻ͢ͳΘͪ Container Local ͳ σʔλͱͳΔ 
 ͜ͷͨΊɺ Custom Cache Handler + ElastiCache ͳͲΛ࢖ͬͯɺӬଓԽํࣜΛ AWS ϑϨϯυϦͳ΋ͷʹมߋ͢Δඞཁ͕͋Δ - https://nextjs.org/docs/app/api-reference/next-con fi g-js/ incrementalCacheHandlerPath
  15. ύϑΥʔϚϯε/ଌఆ Next.js Cache ͸ফۃతͰ͋ͬͯ΋ɺ࣮ͦͦ͜͜༻తͳύϑΥʔϚϯε ಉྖҬͰͷ Pages Router ͳϓϩμΫτͱൺֱ͢Δͱɺ΍͸Γ First Load

    JavaScript ͷϘϦϡʔϜʹѹ౗తͳ͕ࠩग़Δ 
 (App Router Ҋ݅͸ґଘϥΠϒϥϦ͕গͳ͍ͨΊɺʮͦΕ͸ͦ͏ʯͱ΋ݴ͑Δ͚Ͳ) - App Router Ҋ݅: ໿ 200 kB 
 Pages Router Ҋ݅: ໿1,720 kB
  16. ࡉཻ౓ͳςετ - શͯͷ Component Ͱ Storybook ͷ ϑΝΠϧ (.stories) ࡞੒Λڧ੍͓ͯ͘͠

    - RSC ͷςετํ๏ʹ͍ͭͯ: - ඇಉظͳ SC ʹ͍ͭͯ͸ɺ Container / Presentation Ͱ෼ׂ͓͖ͯ͠ɺStorybook ΍ jest Ͱ࣮ߦ͞ΕΔͷ͸ Presentational ͳ෦෼ͷΈʹ͓ͯ͘͠ 
 ※ ৄࡉ: React Server Component ͷςετͱ Container / Presentation Separation - ͢΂ͯͷ Story ʹରͯ͠ɺjest + RTL Ͱ composeStories & render ͷಈ࡞อূΛ͓ͯ͘͠ - Storybook 8 ͷ experimentalRSC ͸࢖͍ͬͯͳ͍ 
 ※ ։ൃ౰ॳ͸ Storybook 7.x ͩͬͨͱ͍͏ͷ΋͋Δ͕ɺSC Λ ແཧ΍Γؾຯʹ CC ͱͯ͠ ѻ͍ͬͯΔ͜ͱࣗମ͕Πέͯͳ͍ͱࢥ͍ͬͯΔͨΊ
  17. ૈཻ౓ͳςετ - Playwright ʹΑΔ E2E Λ࣮ࢪ - DB ͷ Seed

    + Spring Boot ͷىಈ + next start Λ͢΂ͯ CI Ͱ Service ࣮ߦ ͢ΔΑ͏ʹ͍ͯ͠Δ - Pros: E2E ͱͯ͠͸ਖ਼͍࢟͠ - Cons: CI ͕ॏ͍ͨ. SA ΛҰ౓࣮ߦͯ͠͠·͏ͱ DB ͷঢ়ଶ͕มߋ͞ΕΔ ͨΊɺFlaky Λ౿ΜͰ΋ Playright ͰಉҰ URL ʹϦτϥΠͯ͠΋ҙຯ͕ແ ͍ - Next.js ͷ Experimental Test Proxy ͸ར༻͍ͯ͠ͳ͍
  18. ૈཻ౓ͳςετ - Next Server ͷڍಈͱີʹ࿈ಈ͢ΔՕॴ͸ E2E ଆͰಈ࡞Λ୲อ͢ΔΑ͏ ʹ͍ͯ͠Δ - ςετγφϦΦͷྫ:

    - લఏ: SA Ͱ revalidatePaths Λ༻͍ͯ Router Cache Λύʔδ͍ͯ͠Δ - γφϦΦ: ϖʔδදࣔ -> SA ࣮ߦͯ͠ը໘ભҠ -> ϒϥ΢βόοΫ - ֬ೝ؍఺: ϒϥ΢βόοΫޙͷදࣔͰ͸ Router Cache ͕࠷৽Խ͞Εͯ ͍Δ͔ʁ
  19. App Router ʹऔΓ૊Ή্Ͱॏཁͱ ࢥ͏͜ͱ - App Router Ҋ݅Λ௨ͯ͠গͣͭ͠ཧղ͖ͯͨ͜͠ͱୡ: - RSC

    ͷϝϯλϧϞσϧ - σʔλϑΣονͷཻ౓ - HTML / CSS ஌ࣝͷॏཁੑ
  20. RSC ͷϝϯλϧϞσϧ ·ͣ͸ϑϩϯτΤϯυͷ։ൃऀશһ͕ RSC ʹ೴ΛΞοϓσʔτ͢΂͖ - RSC (App Router) ͸

    Pages Router Ͱͷ SSR ͱຊ࣭తʹҙຯ͕ҟͳΔ - ʮSC ͸ࣄલܭࢉͰ͋ΔʯΛୟ͖ࠐΜͰ͓͘ - ࢀߟʹͳΔ΋ͷ - uhyo ͞Μͷهࣄ: https://zenn.dev/uhyo/articles/react-server- components-multi-stage
  21. σʔλϑΣονͷཻ౓ - Pages Router ࣌୅ʹʮࣄલॲཧʯʹ૬౰͍ͯͨ͠΋ͷ: 
 getServerSideProps or getStaticProps -

    ͜ΕΒ͸ɺPage ୯Ґͷ Component ʹ͔͠࡞༻Ͱ͖ͳ͔ͬͨ - → gSSP Ͱར༻͢Δ API ͷઃܭ͕ϢʔεέʔεʹҾ͖ͣΒΕΔ
  22. σʔλϑΣονͷཻ౓ - App Router Ͱ͸ SC ͕σʔλͷऔಘͱ͍͏ࣄલॲཧΛ୲͍ͬͯΔ - σʔλऔಘ͕ page

    ୯ҐͰ͋Δඞཁ͕ແ͍. ຤୺ͷ Component Ͱɺͦ ͷ Component ͕ඞཁͳσʔλΛ௚઀ϑΣονͰ͖Δ - Ϧιʔεࢤ޲ʹج͍ͮͨ API ઃܭͱ਌࿨͢Δ - ࡉཻ౓ API ͱ͓͍ͯͨ͠ํ͕ɺNext.js ͷ Data Cache ʹ΋ࡌͤ΍͍͢ ͸ͣ
  23. HTML / CSS ͷ஌ࣝ - HTML + CSS ͷ஌ࣝ͸ෆඞཁͳ CC

    Λ࡟ݮ͢Δ্Ͱ΋ॏཁ - ྫ: ΧϧʔηϧͬΆ͍ݟͨ໨ͷίϯϙʔωϯτ - CC ͷ JavaScript ॻ͔ͳͯ͘΋ɺCSS ͷ scroll-snap Ͱ࣮ݱͰ͖·͢Α Ͷʁ - https://web.dev/blog/interop-2022