音声書き起こし
1. オープニング/ゲスト紹介
@spring_raining
こんにちは、UITの玉田です。ユーザーインターフェイスとテクノロジーを愛する開発のためのポッドキャストUIT INISIDE、今回もやっていこうと思います。
今回はですね、ずばりNext.jsバージョン15RCの内容について、今回は浪間さんという方をお呼びしましてお話していこうかなと思います。
よろしくお願いします。
@ynamima
よろしくお願いします。
@spring_raining
それでは、いきなりなのですが、自己紹介などをお願いしてもよいでしょうか。
@ynamima
はい。浪間と申しますと、元々23新卒でヤフーに入社してヤフーの方の販促系の開発に携わってたんですけども、今期は主にLINEで応募に関する新規開発案件の開発に携わらせていただいています。はい。よろしくお願いします。
@spring_raining
よろしくお願いします。浪間さんは元ヤフーの方で入社になってるっていうことで、合併以来、徐々にUITサイドもLINEもLINE以外の方も。はい。呼んでいこうかなと思っていまして、今回も。はい。是非いろいろなことについて話していければなと思います。はい。
2. Podcast収録のきっかけ
@spring_raining
ではですね、ちょっとその本題に入る前にきっかけについて話そうかなと思いますが、ちょっと内輪の勉強会。私たちはビジネスプラットフォーム開発本部というとこに
@spring_raining
所属しているんですが、その中で技術共有会を開きました。
で、今回もそうなんですが、元LINE元ヤフーのフロントエンドの開発者を中心にいろいろな勉強会や、今回の場合だとこう発表など、LT会みたいなのですね。はい、開きまして、いろんな話をしていきました。
@spring_raining
で、その中で、個人的に気になった今回のトピックについて発表されていた浪間さんをお呼びしたという経緯になっております。で、今回、Next.jsについて話していくのですが、結構私たちのチームではあまりNext.jsを業務で使う機会はなかったりして、色々と新鮮なトピックではありました。
@spring_raining
さらに今回結構おっと思ったのが、まだ正式なステーブルリリースではないNext.js 15について、もう実際に使ってみたという話でしたので、これはせっかくなので色々と聞いてみたいなと思った次第です。
3. Next.js 15 RC採用の経緯
@spring_raining
今回はどういったところでNext.jsのバージョン15のプロダクトを使いましたかね。
@ynamima
はい、Next.js 15を使った流れなんですけども。で、今回新規開発してるサービスのエンドユーザー向けのフロントエンドの画面はNext.js 14で開発進めていまして、で、そちらの入稿管理機能の方が、基本的には我々開発の中で触るっていう、開発メンバーが入稿のデータを受け取って入稿するというようなツールで、社内に閉じるようなものなんですけども、そのツールが欲しいねってことで、作り始めることになりまして。
@ynamima
Next.js 14で作ろうかというのもあったんですけども、自分たちだけで社内で閉じるツールなので、そんなにしっかりしたっていうとあんまり良くないですけど、ちょっとぐらいまだステーブルになってないもの使ったとしても、そんなに大した大きな問題は起きないだろうと。そのフロントエンド側で使ったところで、そんなに大きな問題にはならないので、まあ技術の勉強という点も含めてやってみようというところと、Next.js 14までのキャッシュコントロールがちょっと面倒で、今作ってるサービスが、ヤフー環境の全社で標準的なPaaSの方でとデプロイするような環境で作ってるんですけども、そこだとKubernetes環境でPodが複数立ち上がるような環境でサービスを展開してて、
@ynamima
そのような状態で、その複数Pod間でのキャッシュの共有とかがちょっとめんどくさい。はいっていうの、Redisかませるのとかあったりとかで、それをなんか簡単に作りたい、パパっと作りたい、管理画面のためにその辺を組むのとかもちょっとめんどくさいとかもあって。で、Next.js 15はキャッシュ管理がNext.js 14よりは楽になってるっていうのとかもあって、ちょっと魅力的だなっていうところで、15でやってみようっていうので、開発を始めました。
@spring_raining
なるほど。ありがとうございます。今回のその対象の画面、画面というかプロダクトは、基本的には新規内部向けのサービスっていう形で、結構こう、自由度が高かったっていうところと、あと、あれですかね、タイミング的に結構ちょうど良かったんですか。
確か15のRCの発表が5月6月ぐらいだったのかなと思うんですけど、開発自体はいつ頃されたんですかね。
@ynamima
そうですね。タイミングがめちゃめちゃちょうどよかったですね。出たのいつでしたっけ。なんか4月ぐらいだっけな。
@spring_raining
はい。うん。
@ynamima
サービスの自体の、その、エンドユーザー向けの方のバックエンドとフロントエンドの開発着手が4月からで。で、この入稿機能を作り始めようってなったのが5月の中頃からで、そのくらいの時期にはNext.js 15のRC版が出てて、めちゃめちゃホットでいいじゃんっていうのもあって。
@spring_raining
ところですね。じゃあそうですね、ほんとにタイミングよくこう試せる機会が来たっていうところ、いいですね。はい。じゃあそうですね。そのキャッシュのところの違いとかも。はい。この後、14と15の違い、多分だいぶ違うのかなと思うので、是非聞いていければなと思います。はい。
4. Next.js 14→15の変更点
@spring_raining
Next.js 14、15RCの変更点についてですね。一応Show noteの方に15RCのリリースのブログの記事を
@spring_raining
載せておきますが、その中で今回メインに取り上げようかなと思うのはパーシャルプリレンダリングですね。の機能について今回はちょっと詳しく見ていこうかなと思います。
で、ではですね。このパーシャルプリレンダリングは、実際にこのサービスで使ってみたところではありますか。はい、
@ynamima
これを組み込んでみて、そうですね、Next.js 15の多分1番大きい目玉機能っぽい感じで。なので使ってみています。
@spring_raining
うん。なんかざっくりと説明結構難しいと思うんですけど、今までのストリーミングSSRと呼ばれる方法だと、スタティックレンダリングとダイナミックレンダリングのこう2つ区別があって、で、その中でサーバーサイドレンダリングされるものっていうのは、基本的にプリレンダーという機能がなくて、その都度こうレンダリングされるっていうのが基本的な考え方でしたが、パーシャルプリレンダリングはそれを部分的にあらかじめレンダリングするという認識であってますかね。
@ynamima
自分をちょっと言葉にすると認識がちょっと怪しい。怪しいところがあるので、ちょっと下手なこと言って全然間違ってたら怖いなって思いつつ喋るんですけども。そうですね、HTMLの1枚のHTMLとして出力する状態の時に、今まではそのAPIへのフェッチなどの内容があって
@ynamima
動的に変わる部分、SSRで動的に変えなきゃいけない部分がある場合に、それらをキャッシュし、フェッチでデータを取ってきてから、HTML全体をSSRで描画してブラウザに配信するっていうのが、Next.js 14までの機能であったのが、今、今までの既存のSSRで。なので、ブラウザに初めて配信されるようになるのが、
@ynamima
そのすべてのフェッチなどの処理が終わって、ページ全体ペライチを配信できる状態になるまでと、最初の画面が表示できないっていうのが今まで1番遅かった問題点で、それを改善するための方法としては、フェッチなどの処理はクライアントサイドで行うStaticな内容の、ヘッダーとかだったりその描画が変わらない部分のHTMLと、クライアントサイドでフェッチをするためのJavaScriptのスクリプトを合わせて、SSRの、SSGか。サーバーサイドではあらかじめプリレンダリングしておいて、それを配信し、クライアントサイドでフェッチを行わせるようにするっていう方法か。SSRの内容を定期的に更新するようにするISR(インクリメンタルスタティックジェネレーション)によってキャッシュをすることによって、サーバーから取ってきたデータを繰り返し配信して、定期的に
@ynamima
それをリバリデイト、内容を更新することによって確かめるっていう方法の2種類がNext.js 14まであったっていう認識です。
で、パーシャルプリレンダリングからは、Reactの18からかな。で導入されたサスペンスっていうコンポーネントのものと組み合わされて、SSRをする際に動的に変わりうる部分をサスペンスとして
@ynamima
穴を開けた状態で、HTMLの中に穴があって欠落している状態でSSRをでき、その状態で配信をすることができるようになったというような認識です。なので、サスペンスの中のフェッチがまだフェッチをしている状態のときは、フォールバックでスケルトンみたいなコンポーネントを表示したり
@ynamima
しておくことができ、フェッチがサーバーサイドで完了したときに、後追いでそのその情報をHTMLに配信することで、クライアントサイドのスクリプトが動いてるのかな。で動的に書き換えがされて、ただ配信されるHTMLはサーバーサイドでレンダリングされたものが後追いで配信されることによって、全体的にはSSRの挙動で行うことができるという。え、SSRプラスクライアントサイドのフェッチでやってたことをすべてSSRだけで完結できるようになったよ、みたいなのがパーシャルプリレンダリングでやってることというふうに認識しました。
@spring_raining
はい、私も同じ認識です。すごい。ほんとに言葉で説明する難しさありますよね。私も結構こう、手元で色々動かしてみて、1番あれですね、私が理解しやすかったのは、ビルドした後の結果を見る見て、そのパーシャルプリレンダリングしたものは、例えばそのNextサーバーアップの中のHTMLファイルとして出てきて、
@spring_raining
これすごい。今までだとなんかすごいスタティックレンダリングみたいな挙動をしているけれども、実際には、さっきのパーシャルプリレンダリングで穴を開けているという風に表現されていた形のHTMLが最初からあるっていう状態ですね。そうですね。はい、結構あれですね、その出力されたファイルを見るっていうのが、私の場合だと1番理解が進むのかなっていうところですね。
@ynamima
なるほどです。なんか自分の場合は、実際にビルドして動かしてみて、ブラウザからコンソールのネットワークを見てみては、来てるレスポンスが途中で、途中の状態だと止まってて、あとあと、その、同じレスポンスの中で後追いで内容が配信されてっていうのが見れて、おおっていう、ちゃんと配信されてるんだっていうのが見れて、そこでだいぶ理解が自分は進みました。
@spring_raining
なるほどなるほど、そうですよね。私も最初なんかdevサーバーで動かしてみて、なんかこれ、パーシャルプリレンダリングされてるのかどうかみたいな、それはちょっとわからないよなみたいな感じで、結構そうですよね。なんかこう、理解すれば分かるけれども、ちょっとそうですよね。結構仕組みをちゃんと理解しないと難しいみたいなところは、最初はありました。
で、そうですね、はい。パーシャルプリレンダリングの概要についてはそんな感じで、Next.js 15ではプリレンダリングが導入されたっていうところと、
@spring_raining
あと、あれですよね、その、オプションとしては、そのページ単位でパーシャルプリレンダリングを制御するみたいな機能が一応。
@ynamima
はいはい、そうですね。なんだっけ、コンスト。ちょっとその設定でやってないので、ちょっと忘れちゃったんですけど、なんか、ページコンポーネントにコンストで定義してやると、パーシャルプリレンダリングにできるっていうような設定がありますね。
@spring_raining
それですそれです。experimental_pprですかね。そうです、ていう、はい、ものがあるっていう。はい、それで、制御とか色々と柔軟性が、柔軟性っていうか、パーシャルプリレンダリングが、はい、Next.js 15ですごくもう有力な機能として使えるようになっているというところですね。
5. Partial Prerenderingについて
@spring_raining
そういうすごい強力な機能を持つパーシャルプリレンダリングなんですけども、一方で、個人的に結構難しいなと思ったのは、
@spring_raining
結構パーシャルプリレンダリング、実際にこうビルドした時に、その表示としてこのページがパーシャルプリレンダリングされましたみたいな結果とか、あと、これはスタティックなページですとか、あるいはサーバーサイドで毎回レンダリングされますみたいな感じでビルド結果に表示されるんですが、その条件が結構最初わかりづらいなっていう
@spring_raining
風に思ってしまってて。で、そうですね、そうですよね。そこはやっぱりそのキャッシュの設定とかが関係してくるのですが、結構そうですね。その辺りもNext.js 15では変わってきた。
@ynamima
Next.js 15からそのパーシャルプリレンダリングが導入されたことで、キャッシュが、多分VercelのそのNext.jsの全体の戦略として、キャッシュの依存をなくしたいっていう方向性なのかな。で、キャッシュをさせてもいいけどしないというのがデフォルトでできることになったので。できることになったというか、デフォルトでそうなったからそれによって変わっていて。で、正直ちょっと自分もまだ挙動完全には把握できてないところはあって、はい、ここのページはパーシャルプリレンダリングになるはずなのに、なぜかその動的なダイナミックレンダリングなページになっているとかのところがあったりして、見通しの悪さはちょっと否めない感じがありますね。
@spring_raining
そうですよね。一応、その制御方法としては、そのfetch funcitonのオプションでそのキャッシュについて設定をするんですが、そこの設定に応じて、どうやらそのパーシャルプリレンダリングをやったり、サーバーサイドレンダリングになったりっていう形になっていて。あと、サスペンスですね。サスペンスがちゃんと設定されているかどうかっていうところ。
はい。それ、有効化されるかどうかっていうところがあるんですけど。結構。そうですね。私もまだなかなか使いこなせるの難しそうだなっていう気持ちは一部ありますが。
そうですよね。ただ、14から15によってそのデフォルトの設定が変わったっていうのは、そのキャッシュの戦略がやっぱり15からはこうなんですかね。キャッシュさせる場合はこう明示的にキャッシュさせるみたいな意図を持った変更なのかなと思うんで。
@spring_raining
うんうん、どうですかね。私個人としては15の方が直感的な気はしますが。ただちょっと、そうですね。私はどうだろうな、多分全部明示的に設定するのがわかりやすいかなと思ってしまいそうですね。
@ynamima
そうですね。14までの勝手にキャッシュされるは逆にすごいハードル高くなってた。App Router導入のていうのが一部緩和された要素ではあるのかなという。Next.jsの難しい要素が一部緩くなって、ちょっと扱いやすくはなったと思うんですけど、まだ。そうですね。
@ynamima
サスペンスをちゃんと設定できているかっていうハードルが出てきたりとか。あとは、クライアントコンポーネントとサーバーコンポーネントの見分けが。見分けというか、見通しの悪さ。ちゃんと今このコンポーネントはサーバーサイドでレンダリングできているのだろうか。などの見通しがコード上で1発でわからないとかがちょっと難しいところだなって思いますね。
@spring_raining
そうですよね。14と15を両方開発として使っているっていうことだと思うんですけども、結果的にこう、なんて言うんですかね、こう、すごい両方を使い分けることで、すごい、なんかこう、何かこう違うなって思うところとか、それともそんなにこう、例えば14から15にアップグレードするときにそんなに困らないかなとか、
@spring_raining
結構アップグレードの時の所感とかも、もし今の時点であれば聞いていきたいのかなと。
@ynamima
でも、14でどこまでの構築をしてるかによると思うんですよね。その14で、ちゃんとそのキャッシュサーバーと、でもあれか、セルフホスティングの話もあるので、Next.jsって、その、セルフホスティングするかVercelのサーバー使うかでだいぶなんか違うのも確かにある。だってセルフホスティングだとキャッシュ管理がめちゃめちゃめんどくさいとか、なんかちゃんとNextの活かしきれてるのかとかがいろいろ問題があるんですけど、
@ynamima
そのセルフホスティング前提で話すと、その、ちゃんとキャッシュサーバーとか組んだりしてると、ちょっとその辺がいらなくなるのは楽にはなるのかな。でも、だいぶ実装としても変わっちゃう気がする。
その、今まだRC版で、なんかRC版が結構長くて、まだ全然ベータとかすらこないので、まだ全然どういう感じになるかわからないですが、基本的には多分ほとんど全部をPPRにしてくことになるとは思うので、Next.js 15を導入すると、その、あんまりISRにしておくメリットが感じられないと今触ってみて思うので、理由がない限りはおそらくパーシャルプリレンダリングを導入するかに変わっていくかなと
@ynamima
思うんですが、その際に、フェッチをどれだけ書いているかとか、設定がどれだけあるかで、Next.js 14でそんなに、Next.js 14自体が出てからまだそんなに経ってないので、そんなに複雑化したアプリケーションができてる人はいないと思うんですけど、なるほど。移行するってなったら、そんなに大変ではないけど、なんか考え方を変えなきゃいけないから、ちょっと勉強は必要かなとは思います。
@spring_raining
なるほど。そうですよね。結構、そのApp Router導入時点でも、もうめちゃくちゃ変わったのに。みたいな、
@ynamima
いや、ほんとに何回変えるんだっていう、App Router入ってすぐじゃんっていう。まだ13.、いくつだっけ。って入ってばっかなのにっていう感じですね。ほんとに
@spring_raining
あれですね。逆に言うと一気に。いや、でもそれはあれですかね。単純にApp Routerに移行するのがすごくコストは高そうではありますが。14から15もそうですよね。すごい皮肉ではあるんですけど、14の機能を取り、すごく積極的に取り入れたら、変更の考え方も入る必要があるっていう。そうです。ところが結構悩ましいですよね。あと
@ynamima
13以下、12はもうEOLだっけな。13からApp Router。まだページルーターのアプリケーションをApp Routerに乗り換えようって時は、なんか急いで今14にするよりは、15を待った方が簡単かなっていう。その14にしたと。15でどうせまた大きく変わらなきゃいけないところがあるので、なんかそういうマイグレーションしなきゃいけない場合は、15がおそらくあと半年1年くらいで来るんじゃないかなっていう感じがするので、
@ynamima
15でPPRがちゃんとステーブルになってからの方が楽そうだなとは思います。
@spring_raining
確かに単純にそうですよね。14のリリースから15のリリースまでそれほど時間が経ってないっていうところは結構ある。ある意味こう、それまで移行を待ってるプロジェクトとかも多いので、そういう意味では確かに15待ちっていうのがすごいいいところではありますよね。そうですね。
@spring_raining
他に色々と変更点とかはあるんですが、今回の、せっかくなので、今回技術共有会でどういったことを取り上げたのかっていうと、というところについて紹介していこうかなと思います。
6. 技術共有会で話せなかったこと
@spring_raining
今回、その勉強会、技術共有会でいろいろと話していただいたんですが、今回、Next.js 15の話だけじゃなくて、あれですね、そのReactサーバーコンポーネント自体のこうについて、結構私もそれほど、めちゃくちゃこう、バリバリ使ってるっていうほどではないので、最初に、こう、Reactサーバーコンポーネント触って、罠だったなって思うuse clientのところとかの話とかも結構興味深かったし、
@spring_raining
あと、その、Next.jsの中のフェッチって実は普通のフェッチと違うみたいなところとかも、色々とこう、罠の部分を紹介されて、で、結構ためになったので、じゃあちょっとuse clientのところをお話していこうかなと思いますが。サーバーコンポーネントからクライアントコンポーネントを呼び出せるのかとか、そういったところとかも今回その話の中でまとまっていたんですが、結構これは詰まりポイントですよね。
@ynamima
そうですね。あれ、これがReactサーバーコンポーネントの仕様なのかNext.jsの仕様なのかが、自分、ちょっと今ちょっと定かではないんですけど。
@spring_raining
はい。ここではあれですね、Next.js上の仕様ということにしましょうか。
@ynamima
はい。ちょっとごめんなさい。これがReactサーバーコンポーネントのことの話をしちゃってたらちょっと申し訳ないんですけど、ちょっと一緒くたにして話しちゃいますね。はい、はい。なんか、クライアントコンポーネントを使うためには、そのuse client使うみたいなので、なんか、use clientにしたら、クライアントコンポーネントになるからっていうので、use client、とりあえずクライアントコンポーネントの上に書いときゃいいんだってなりがちなのが、多分最初に学ぶとあるなってめちゃめちゃ思うんですけど、自分も最初そんな感じで理解しちゃってて。
@ynamima
でも実際は、クライアントコンポーネントから呼び出したら、その先はクライアントコンポーネントになるので、クライアントコンポーネントからインポートされたコンポーネントは、サーバーコンポーネントからクライアントコンポーネントの境界を超える際の制約っていうのが発生して、use clientをつけると、サーバーコンポーネントとクライアントコンポーネントの境界だというふうに認識されるので、その制約が発生してしまい、
@ynamima
その関数とかのシリアライズして、サーバーからブラウザ側にシンプルなテキストとして渡せない、HTML文字列として渡せないようなオブジェクトがプロップスとかで渡せなくなっちゃうという制約が追加されてしまうので、クライアントコンポーネントにはuse clientってつけておけばいいっていうのは間違いであって、できる限りuse clientっていうのはあんまりつけるべきではない。サーバーコンポーネントからクライアントコンポーネントを呼び出すときにつけるものっていうことになっているっていうのに気づくと、すごい。なんか、じゃあどうしたらいいんだってなって、その結局、普通に何も書いてないコンポーネントはサーバーコンポーネントにもクライアントコンポーネントにもなりうる。で、どっちで使われているかっていうのは、どこからインポートされているか。一度もクライアントコンポーネントを挟まずにインポートされているのであればサーバーコンポーネントだし、1回でも祖先のコンポーネントにクライアントコンポーネントがあったらクライアントサイドで実行されるし、っていうふうに変わる
@ynamima
ものなので、コードコンポーネント1個をパッと見て、それがどっちで実行されてるのかが見通しにくいっていうのが、ちょっとNext.jsの今の仕様だと、なんか、なんかなっていうふうに思ってました。
@spring_raining
そうですよね、なんかその初期状態だと、クライアントコンポーネントがクライアントでレンダリングされるか、サーバーサイドでレンダリングされるかが決まってないっていうところがすごいつまずきポイントですね。なんかで、デフォルトだとサーバーなのか。みたいなと言われると、そうでもなくて、みたい。
@ynamima
なんかよくそう言われがちですよね。App Routerの時、デフォルトはサーバーなんだよって。なんかそれは違うんだっていうのをちゃんと認識しないと、罠に陥っちゃうなっていう。
@spring_raining
そうです。難しいですよね。で、サーバーサイドからそのクライアントコンポーネントをレンダリングするときは、そのシリアライズ、プロップスというか、なんなんていうんすかね、こう、サーバーからクライアントにこう、コンテキストが移るので、その境界ではそのシリアライズできるオブジェクトじゃないと渡せない。なので、関数とか渡せないっていう。とかはわかればわかるが。そうですよね。
@ynamima
あと、なんかすごいグローバルにコンテキスト扱いたい時とかってあるじゃないですか。useContextで。すごい。はい。なんかもうHTML全体でそのクライアントサイドのコンテキスト使っといて、いろんなコンポーネントで使い回したりとかがあると思うんですけど、なんかそれをやるためにコンテキストのプロバイダーを設定したらページ全体がクライアントサイドになっちゃうのかっていうと、それもそんなことはなくて、そのコンポーネントからインポートするとクライアントコンポーネントになっちゃうんですけど、サーバーコンポーネントでクライアントコンポーネントをインポートして、
@ynamima
そのチルドレンの要素としてサーバーコンポーネントを渡せば、その下はサーバーサイドとしてレンダリングされていくので、そういうふうに挟むと、コンテキストとかを広くサーバーサイドの境界を超えてクライアントサイドのコンテキストとかを使い回すこともできるっていうのとかも一応知らないとはてなになるなっていう、なんかもつまずきポイントですね。
@spring_raining
そうですよね、あれですよね、私も同じ認識です。なんかこう、クライアントサイドからサーバーサイドコンポーネントを呼び出せはしないけれども、そのクライアントサイド側のチルドレンとしてサーバーサイドでレンダリングした結果を渡すっていうことができるっていうところは、結構ミソですよね。
なので、ただ単純に、そのJSXのツリーが、クライアントサイドの下は全部クライアントサイドになるかっていうわけではない。
@ynamima
そうですね。クライアントサイドの下がじゃなくて、クライアントサイドからインポートされるとっていう言葉の違いがめちゃめちゃ重要っていう。すごい、初学者に優しくないなっていう。
@spring_raining
なので、あれですよね、その、コンテキストの重要度がすごい、コンテキストっていうか、コンテキストの重要度がすごく上がるなっていうのは。うん、その、今の時点での、そうですね、私の感想であります。
@ynamima
そうですね、確かにクライアントサイドの領域が狭まって、サーバーサイドでいろいろやろうってなると、やっぱstateで状態を管理するっていうよりは、できる限りstate使う範囲は小さく狭くしていって、使い回したい情報はコンテキストに押し込もうっていうようになるのがいいんじゃないかなっていう風に今思ってますね。自分も
@spring_raining
そうですよね。結構つまずきポイントではあります。これは。そうですね。私もそうでしたけど、すごいこう書きながらなんか学んでいったっていうところがほとんどですよね。うん、あとはそうですね。ちょっともう1つ、ここは実際には勉強会の時は話せなかった部分ではあるんですが、
@spring_raining
フェッチのところですね、結構これもすごく罠ポイントではあるのですが、さっきのそのフェッチファンクションの中のオプションのところとかもそうなんですが、結構この辺りはこう、Next.js独自の実装、実装っていうか、あまりこうなんて言うんすかね、こう、実は標準のフェッチファンクションとはちょっと違うみたいなところがあったりするんですよね。
@ynamima
そうですね、ちょっとこれ、フェッチについて調べたのは、ちょっとやりたいことがあって、それを実現できなくてっていうところがあったので、ちょっと自分の中で理解がふわふわしてるところもあるんですけど、フェッチは、まずブラウザのブラウザAPIのフェッチと、それをNode.js環境で実行するために作られてるライブラリのnode-fetchっていう2つがあって、Next.jsはそのうちのブラウザAPIの方の
@ynamima
フェッチを拡張していて、その中でそのキャッシュのための型とかだったりを追加できるようになっているものが使えるようになっている、ていう認識です。まずで、はい。ブラウザAPIの方のフェッチを、確かもうすでにNode環境で特に何もなく、すでにそれを、それを使えるので、node-fetchのほうは現状今いらない存在になってるんですけど、自分が開発してた環境の中でちょっとやりたかったことが
@ynamima
ありまして。イメージ的には、curlとかで叩くときにプロキシヘッダーを設定できるじゃないですか。はい。curl叩くときにプロキシで、ここをプロキシーサーバーにして叩くっていうことができると思うんですけど、Next.jsのサーバーアクションから外部のAPIを叩くときに、ヤフーのプラットフォーム環境の社内ツールで今デプロイしてる環境のネットワークセグメントの制約的に、外部のネットワークを叩きに行けないんですね。社外のネットワークをなるほどという制約がありまして、
@ynamima
それを叩くためにはプロキシサーバーを経由させる必要があるんですね。なので、画像を入稿してるのは、社内の別のプラットフォームのところで画像をデータを配信していて、で、それを見に行くには普通にそのドメインを叩いてアクセスするんですけど、それは社外のネットワークとして開かれてるドメインなので、プロキシをかまさないと叩け、その画像を取得できないんですよ。
@ynamima
Next.jsがサーバーサイドなので、クライアントサイドで実行すれば取得できるんですけど、Next.jsのイメージコンポーネントでアクセスしようとすると、サーバーサイドでフェッチしに行くので取れないんですよ。
@spring_raining
わかりますわかります。はい。
@ynamima
なので、プロキシをどうにか噛ませらんないかなっていうのを調べたんですけど、ブラウザAPIのフェッチだとプロキシを噛ませるためのオプションが存在していなくて。おお。で、なぜかブラウザAPIをNode.js環境で実行するために再現されたもののはずであるnode-fetchだとプロキシを噛ませられるんですよ。なるほど。で、Next.jsの方でどうにかできないかなって思ったんですけど、結局自分が調べた限りだとあんまりうまくいかなくて、今は無理やりNext.jsでプロキシって調べると、Next.jsのサーバーが、自分自身がプロキシとして
@ynamima
プロキシを立てるAPIルートを使ってプロキシングをするみたいなのばっかで、なんか情報が出てきてしまって、外部のプロキシサーバーを使うっていう方法がなかなかなくて、なので、今は無理やり自分自身のAPIルートの中でプロキシをして、その中でnode-fetchを使って外部のプロキシサーバーを使うっていう、はい、実装しているすごい変な状態で、どうにか取得するようになりまして、これがどうにかなってくれないかなっていう、なんか愚痴というか、調べてできなかったですってことを、その、LT会の時に混ぜて資料に書いてました。
@spring_raining
なるほどなるほど、そうですね、どうなんでしょうね。Next.js側からすると、そういう、なんて言うんすかね、そのサーバー、APIサーバーを提供する機能があるから、使い方としては間違ってなさそうな気はしますけど、あれですよね、なんか、フェッチを、フェッチからフェッチを呼び出すAPIを、そう1個用意する
@ynamima
認識イメージこれは想像なんですけど、ブラウザAPIのフェッチはブラウザ環境で動くものだから、クライアントサイドでスクリプトを実行された時に、悪意あるサイトで変なプロキシサーバー経由して通信するっていうことをされた場合に困るから、ブラウザサイドのやつではそういうプロキシを行うっていう設定がないのかなって思ってて。でもNext.jsのフェッチは基本サーバーアクションで行うから、サーバーサイドでやるんだからなんかいいじゃん。
@ynamima
でプロキシさせてくれよっていう風ななんか願望
@spring_raining
あります。そうですね。確かにNext.jsの主張の一貫性はわかりますよね。その、フロントエンドでもサーバーサイドでも同じ動きをしなければいけないっていう。
@ynamima
そうですね。
@spring_raining
っていうところですよね。うん。
@ynamima
ちょっと今、今喋った内容はめちゃめちゃ想像なので、すごいなんかとんでもないこと言ってるかもしんないです。
@spring_raining
ああ、いえいえ、確かにそうですね。今話したフェッチの3種類の中で、やっぱりどれが別かっていると確かにnode-fetchな気はします。
でも、じゃあなんでnode-fetchがインポートできるようになってるのかっていうところは謎ではあるんで。
@ynamima
そう、そうなんですよね。そのnode-fetchをNext.jsで使ってしまうと、Next.jsのエコシステムでキャッシュコントロールがあるのに、node-fetchを使うとそのキャッシュコントロールから外れちゃうので、キャッシュしてくれなくなっちゃうっていうのもあって、なんかせっかくNext.js使ってるのになっていう気分にもなってしまうんですよね。
うん。だから、でも、かといってAxiosとかをわざわざ使うのもねえってなるし。
@spring_raining
それはそれでそうですよね。結局なんかフェッチファンクション使うことになりますし。そうです。
@ynamima
うん、そうですね。
@spring_raining
そうですよね。フェッチのところとかは本当にあれですよね。こうわかってないとなかなかいきなりだと結構難しいところではありますよね。
@ynamima
はい。なんか、なのでもう完全にこれは僕が知らないやつなので、Next.jsのフェッチでどうにか外部のプロキシサーバーをプロキシする方法があったら誰か教えてほしいです。
@spring_raining
どうだろう。なんか結局、でもさっき話した回避方法が1番こうなんて言うんですかね。結局それに落ち着いてしまうかもしれないですね。そういう主張なんだろうと思います。色々とつまりポイントがある中で、結構Next.js、割と入社されてからすごくこうキャッチアップした感じですかね。めちゃくちゃ最新の情報とかも追われていて、
@ynamima
入社するまではあんま触ったことがなかったので、入社してからのここ1年ぐらいですごいNext.js触って勉強しているので、すごいまだ勉強途中なんですけど、最近のここなんで、ここ1年ぐらいのNext.jsしか知らないですね、自分は。
@spring_raining
いやもうむしろ多分そっちの方がなんかこう、変に昔のNext.js知ってる人とか、そうそうNext.jsの知識とか持ってたりするよりもめちゃくちゃいい気がします。
結構割となんやかんやでこう、ドキュメントとかはこう、すごく充実してるところはあると思うんで、そうですよね。あとは今回のような、そのNext.jsについてのこう、知見とかを、今後も私たちのチームの中でこう、中でもいいし、もっと外にですね、なんかこう、話していける機会とかがあると
@spring_raining
良いかなと思います。本当に私も今回の情報共有会めっちゃ参考になりました。
@ynamima
ありがとうございます。ありがとうございます。そうですね、なんか自分はReactがめっちゃ好きなんですけど、合併してLINE側ではあんまりReactが使われてないっていうので、ちょっと今、どっちかというと、自分の所属が今LINE側に近いところにいるので、ちょっと、ちょっと悲しいので。
で、なんかNext.jsで、サーバーサイドレンダリングでいい感じにできるんだぞっていうのをちょっと広めてって、みんな使ってもらえるようになればなっていう風に思ってます
@spring_raining
ですよね。はい。もうせっかく人はいっぱい増えましたので、いろんな、本当にそうですね、今まで使ってないフレームワークとかもの、こう、どんどん取り入れていけたらなと思います。はい。
7. クロージング
@spring_raining
というわけで、今回はNext.js 15RCについて話していきました。LINEヤフーのフロントエンド開発者コミュニティでは、このようなフロントエンドに関する議論や意見交換を日々行っています。
今後もLINEヤフーに関するフロントエンドの情報をどんどん公開していきますので、ぜひチェックしてみてください。また、このポッドキャストに関するご意見、ご感想についても受け付けています。
@spring_raining
#UIT_INSIDE で投稿をしていただきますと、スタッフの方で拾います。それでは浪間さん、ありがとうございました。
@ynamima
ありがとうございました。