Slide 1

Slide 1 text

PATCH didn't work @Quramy 2024.9.18

Slide 2

Slide 2 text

About me - id: @Quramy (GitHub, X) - ৬छ: Web ϑϩϯτΤϯυΤϯδχΞ - Next.js ͱͷؔΘΓ: - gIP, gSSP, gSP (ISR), RSC ͷҰ௨Γ͸ܦݧࡁ - 2023೥6݄ࠒ͔Β App Router ར༻Ҋ݅ͷ։ൃʹ΋ܞΘΔ

Slide 3

Slide 3 text

App Router Ͱ஍ຯʹࠔͬͨ͜ͱ - Next.js ͷ Cache ͷڍಈ - Datadog APM ࿈ܞ - msw ࿈ܞ

Slide 4

Slide 4 text

App Router Ͱ஍ຯʹࠔͬͨ͜ͱ - Next.js ͷ Cache ͷڍಈ - Datadog APM ࿈ܞ - msw ࿈ܞ ͜ΕΒʹ͸ڞ௨͍ͯ͠Δ఺͕͋Δ

Slide 5

Slide 5 text

Զͷ fetch ͸ԚΕ͍ͯΔ

Slide 6

Slide 6 text

ઌʹஅ͓͖ͬͯ·͢ ࠓ೔ͷ࿩ʹ͸ಛʹ༗ӹͳ݁࿦͸͋Γ·ͤΜ

Slide 7

Slide 7 text

fetch API ͸ਓؾऀ ҎԼ͸શͯ globalThis.fetch ʹϞϯΩʔύονΛ౰͍ͯͯΔ - Next.js - Datadog SDK - msw/node ࠓ೔͸ fetch ύον͕িಥͨ͠࿩Λ͠·͢

Slide 8

Slide 8 text

Next.js ͷ fetch ύον ͓͞Β͍

Slide 9

Slide 9 text

Request Memoization - App Router ʹ͸ 4 छྨͷΩϟογϡ͕͋Δ - Request Memoize ͱݺ͹ΕΔΩϟογϡ͸ React ͕ fetch API ʹύον Λద༻͢Δ͜ͱͰ࣮ݱ͞Ε͍ͯΔ - ͨͩ͠ React 19 Ͱ౰֘ύονίʔυ͸࡟আ͞Εͨ ୅ΘΓʹ Next.js ͕ fetch ʹಉ༷ͷύονΛద༻͢ΔΑ͏ʹͳ͍ͬͯΔ https://github.com/vercel/next.js/pull/65058/ fi les#diff- 9389e7475a89a826ddfd492b54b3314fc14d53b375f806f3197ed9a69 9e2b3a6

Slide 10

Slide 10 text

https://nextjs.org/docs/app/building-your-application/caching#request-memoization

Slide 11

Slide 11 text

Data Cache - App Router Ωϟογϡ ࢛ఱԦͷҰப, Data Cache - ෳ਺ͷ Next.js ΁ͷϦΫΤετؒͰڞ༗͞ΕΔΩϟογϡ (Request Memoize ͸ ϦΫΤετείʔϓ) - Data Cache ΋ fetch Λύον͢Δ͜ͱͰ࣮ݱ͞Ε͍ͯΔ const res = await fetch('https://dummyjson.com/products/1', { next: { revalidate: 3600, tags: ['product', '1'], }, }) const data = await res.json()

Slide 12

Slide 12 text

https://nextjs.org/docs/app/building-your-application/caching#data-cache

Slide 13

Slide 13 text

ΦϓτΞ΢τͰ͖Δʁ - Request Memoize: جຊతʹΦϓτΞ΢τෆՄೳ - Data Cache: fetch Φϓγϣϯʹ cache-control: no-store Λ෇༩͢Δ͜ͱ ͰΦϓτΞ΢τՄೳ ※1 Next.js v15 Ҏ߱Ͱ͸ no-store ͕σϑΥϧτͱͳΔݟࠐΈ ※2 Data Cache ͷΦϓτΞ΢τํ๏͸ଞʹ΋ଘࡏ͢Δׂ͕Ѫ - ʮNext.js ͕ fetch Λύον͢Δʯ͜ͱͦΕࣗମ͸ෆՄආ

Slide 14

Slide 14 text

ࠔͬͨ͜ͱᶃ Datadog APM

Slide 15

Slide 15 text

APM ͱ෼ࢄτϨʔε - Datadog APM ʹݶΒͣɺҰൠతʹ෼ࢄτϨʔεͰ͸ Outgoing ͳ HTTP Request ʹ HTTP Header Λ࢓ࠐΉ͜ͱͰαʔϏεؒͷ Span Λඥ͚ͮΔ - Next.js App Router Ͱ͸ instrumentation.ts Ͱܭ૷ΛॳظԽ͢Δ͜ͱ͕ ਪ঑͞Ε͍ͯΔ Next.js request GET / fetch GET http://my-service/api/hoge fetch GET http://my-service/api/fuga my-service request GET /api/hoge my-service request GET /api/fuga

Slide 16

Slide 16 text

Datadog APM ໰୊ https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation

Slide 17

Slide 17 text

Datadog APM ໰୊ - ͕ɺdd-trace(= Datadog APM SDK) ͕ instrumentation.ts Ͱ͸ಈ͔ͳ͍ - https://github.com/DataDog/dd-trace-js/issues/3457 - ্هͷ issue ͸ෳ਺ͷ໰୊͕ࠞࡏ͍ͯ͠Δ͕ʮNext.js - όοΫΤϯυ αʔϏε ؒͷ Span ͕ඥ͔ͮͳ͍ = ෼ࢄτϨʔε͕࠾Εͳ͍ʯͱ͍͏ ࣄ৅͕ى͖ͨ - Next.js v14.1.0 Ͱमਖ਼ͣΈ

Slide 18

Slide 18 text

Datadog APM ໰୊ - fetch API ͷύονͷڝ߹͕ݪҼͩͬͨ - 1. Next.js ͕αʔόʔىಈ࣌ʹ fetch API ΛهԱ - 2. instrumentation.ts Ͱ dd-trace ͕ fetch Λύον - 3. Next.js ͸ 1. ͷ fetch ʹύονΛ౰ͯͯར༻ (2. ͷύον͕ແ͔ͬͨ ͜ͱʹ͞ΕΔ)

Slide 19

Slide 19 text

ࠔͬͨ͜ͱᶄ msw ͕࢖͑ͳ͍

Slide 20

Slide 20 text

msw ໰୊ - msw ͱ͸ - https://github.com/mswjs/msw - HTTP ௨৴ΛϞοΫ͢ΔͨΊͷϥΠϒϥϦ Next.js request GET / fetch GET http://my-service/api/hoge fetch GET http://my-service/api/fuga

Slide 21

Slide 21 text

msw ໰୊ - msw ͸ͲͷΑ͏ʹ fetch ΛΠϯλʔηϓτ͍ͯ͠Δͷ͔: - ϒϥ΢β: Service Worker Ͱ HTTP ௨৴ΛΠϯλʔηϓτ - Node.js : fetch API ʹύονΛ౰ͯͯ HTTP ௨৴ΛΠϯλʔηϓτ

Slide 22

Slide 22 text

msw ໰୊ - React Server ଆͰಈ࡞ͤ͞ΔϞδϡʔϧ (e.g. Server Component ΍ Server Action) ʹͯɺ msw/node ͕ར༻Ͱ͖ͳ͍ - https://github.com/mswjs/msw/issues/1644

Slide 23

Slide 23 text

IUUQTHJUIVCDPNNTXKTNTXJTTVFT

Slide 24

Slide 24 text

msw ໰୊ ҎԼίʔυ͸ύοτݟ͸ಈ࡞͢Δ͕ "next dev" ؀ڥͰෆՄղͳڍಈΛࣔ͢ (Ϧϩʔυ͢Δͱϋϯυϥ͕ۭৼΔ) import { http, HttpResponse } from 'msw' import { setupServer } from 'msw/node' if (process.env.NODE_ENV !== 'production') { const server = setupServer() server.use( http.get('https://dummyjson.com/products/1', async () => { return HttpResponse.json({ id: '1', name: 'Hi', price: 100, }) }), ) server.listen() } export default async function Home() { const res = await fetch('https://dummyjson.com/products/1') const data = await res.json() return
{JSON.stringify(data, null, 2)}
}

Slide 25

Slide 25 text

msw ໰୊ - https://github.com/vercel/next.js/pull/68193 Ͱमਖ਼͞ΕΔ ※ 2024೥9݄ݱࡏ Next.js ҆ఆ൛ͱͯ͠͸ະϦϦʔε - PR λΠτϧͷ "tweak fetch patch restoration timing during HMR to allow for userland fetch patching" ͔Β΋࡯͕ͭ͘͠௨ΓɺNext.js ଆͷ Hot Module Replacement ͱ msw/node ͷ fetch ύον͕িಥ͍ͯͨ͠

Slide 26

Slide 26 text

HMR Cache https://nextjs.org/docs/app/api-reference/next-con fi g-js/serverComponentsHmrCache

Slide 27

Slide 27 text

(ิ଍) msw ͱ instrumentation.ts - Next.js v14.1~ Ͱ͋Ε͹ɺinstrumentation.ts Λ࢖͏͜ͱͰ msw/node ͷར༻ࣗମ͸ҰԠՄೳ - instrumentation.ts ʹؚ·ΕΔίʔυ͸ dev-server ىಈޙʹมߋͯ͠΋ ࠶࣮ߦ͞ΕͣɺىಈதʹϋϯυϥͷมߋΛޮ͔ͤΔͨΊʹ͸ผͷϋοΫ ͕ඞཁͱͳΔ - msw ͷϢʔεέʔεΛߟ͑Δͱ instrumentation.ts ͸ෆ޲͖

Slide 28

Slide 28 text

Next.js ͸ύονΛ΍ΊΔͷ͔ʁ - ͦ΋ͦ΋ Next.js ͕ fetch Λύον͠ͳ͚Ε͹ɺdd-trace ΍ msw Λར༻͢Δোนʹ͸ͳΒͳ͔ͬͨ͸ͣ - Next.js ଆ΋ʮfetch ͷ֦ுΛ΍ΊΔͭ΋Γʯͱ౤ߘͯ͠͸͍ͨ - https://twitter.com/leeerob/status/1733154383410684148 - v15 Ͱ fetch ͷσϑΥϧτڍಈ͸มߋ͞ΕΔݟࠐΈ - ͔͠͠ɺReact ͷ fetch ύονऔࠐ΍ HMR ΩϟογϡΛߟ͑Δ ͱɺʮfetch API ͷύονʯࣗମ͸౰෼ແ͘ͳΒͳ͍ͷͰ͸

Slide 29

Slide 29 text

Ͳ͏͠Α͏΋ͳ͍ͱ͖ - fetch Λύον͢ΔϥΠϒϥϦ͕ Next.js ্ ͱিಥͨ͠৔߹ͷϫʔΫΞϥ ΢ϯυ: - NODE_OPTIONS ͷ --import (·ͨ͸ --require) Λར༻͢Δ (ΧελϜαʔόʔͰ΋ಉ౳ͷޮՌ͕ಘΒΕΔ͸ͣ) - Next.js ͕ globalThis.fetch Λೝࣝ͢Δલʹɺࣗ෼ͷ౰͍ͯͨύονΛ ׬͓ྃͤͯ͘͞ - ਎΋֖΋ͳ͍ํ๏Ͱ͋Δ͕ɺNext.js v14 Ͱ͋Ε͹͜Ε͕Ұ൪Ϛγ

Slide 30

Slide 30 text

·ͱΊ - Next.js ͸ fetch ʹύονΛ౰͍ͯͯΔ (Request Memoize, Data Cache, HMR Cache) - Next.js v15 Ͱ΋ʮfetch ʹύον͕౰ͨΔ͜ͱʯࣗମ͸݈ࡏ - msw/node ΍ dd-trace ͷΑ͏ͳʮfetch ʹύονΛ౰ͯΔʯྨͷι Ϧϡʔγϣϯͱিಥ͢Δ͜ͱ͕͋Γɺಛʹ Next.js v14.x ͸ෆ҆ఆͳڍಈ Λ͕ࣔͪ͠ - ബණͷ্ͰΪϦ੒Γཱ͍ͬͯΔ

Slide 31

Slide 31 text

ࢀߟࢿྉ - Next.js ͷ fetch ֦ுͱΩϟογϡػߏͷҧ͍Λཧղ͢Δ https://speakerdeck.com/ryo_manba/fetch-kuo-zhang-tokiyatusiyuji- gou-nowei-iwoli-jie-suru - Why Patching Globals Is Harmful https://kettanaito.com/blog/why-patching-globals-is-harmful

Slide 32

Slide 32 text

Thank you!