EP12 - Next.js App Router 開發體驗

上禮拜bun 包子騰空出世 把各個performance benchmark都打趴了

也讓蠻多人和open source project想到加入包子的可能性

Vercel才剛正式支援Bun

只要你有bun的configuration file Nextjs就會預設用包子來做安裝

我好像還沒講到bun是什麼

如果你在前端或是javascript的生態圈待久了你會知道讓一個project成熟和deploy需要很多不同的工具

包括runtime, code transpilation, testing, building, 等等

每一個工具都是個別的library而且每一個都要分開設定

我們待久了可能習慣了但仔細想想還滿麻煩的

有時候還會不同的library互相打架或是確保同一個設定要在兩邊做

bun就是一個集大成的工具 什麼都有

你要寫測試 bundle 抓package 起一個server

bun都可以做到

而且bun除了速度是亮點以外他們也希望能做到最大化的兼容性

意思是node能做的 node的api bun也要能無縫的支援

你用jest寫的unit test那些語法bun也要有

這樣雖然寫bun的人工作會變很多

但這樣讓想使用bun的人的學習曲線變的很緩

不用特別花很多精力去學習一套新的東西

我自己是期待未來表現的

看看這個包子可以帶來什麼變化和給整個生態圈什麼樣的刺激

我本來想用bun的test試試 跑起來真的挺快但現在有個bug讓我沒法繼續

只能等他們修了

最近公司的前端 至少我們這整個大組 來了一個很大的改動

因為這個改動讓我們可以選擇任意框架來做開發

我們組就選了Next尤其RSC來試試看開發我們下一個project

Next.js是基於React的一個meta framework

有自己的routing system,middleware,而最一開始選擇Next可能是因為你的app需要SSR

13.4版之後app router變成了預設的也就是說你可以開始使用React Server Components

RSC是2020年React propose的一個不同的架構和rendering方法

簡單來說 server component只會在server運作最後給到client的是一種特殊format來render你的component

優點是你不用把整個react code ship給client

整體網路傳輸的資料量會變小而且和SSR不同的是他不用SSR傳統的rehydration

結果就是你在client端要下載和跑的code都變少了相對應的就是整體效能的提升

至少這是他們promise的

另一點是你可以在server component裡面直接和database做溝通因為已經在server上了

不過我覺得正常情況下應該不太會有這樣的需求

很多人也是因為看到這個才覺得RSC是不是新的PHP

底下我分享一些我自己用了Next app router的感想

開發者體驗

Vercel應該花了很多時間在開發者體驗上

live reload還沒遇過什麼問題而且我不曉得是不是只有我這樣但如果你改的是server component的話整體感覺比較像是hot module reload沒什麼感覺可是code已經更新了

若是client component比較有感覺是live reload

Vercel也花了大量的時間來確定他們的document是完整的而且時不時會更新確保是up to date

像前陣子就更新了caching和form

若在開發期間遇到error也會有一個overlay告訴目前遇到什麼樣的error

之前Vercel也宣布開發了一個新的build tool叫Turboback可以試試

目前還在beta階段而我自己是沒有用的因為常常遇到錯誤整個dev server起不來

App Router

目前Next app router會是預設的方式來開發你的project

跟之前的pages router最大不同是app router下面的component全部都是server component

除非你特別在檔案上面標use client才會變成原來的ssr要不然都是server component

前面有提到RSC的優點就是使用者整體拿到的total bundle size會比較小

而 這算不算是缺點呢 你需要花點時間習慣怎麼用這個做開發

首先你沒有hooks了 平常用到的reactive hooks like useState useEffect等等都不能用

你若把它想像成是一個JavaScript function我現在call了就要有result會比較容易理解

因為這樣這個component還能掛async 在裡面await fetch call再return jsx

若需要在server上面有state那server component可能不是你要的

加上這樣牽涉到stateful vs stateless

再來你可能會想要最大化的理由RSC的效能優勢

你會儘量使用server component

但有時候你會有想要用到client component時候比如我想要用react hook form

你就會開始拆component

你可能本來一個feature在一個component寫就好最後被拆成幾份

我們目前狀況就是這樣

有時候會有過多的拆分

然後就會開始懷疑人生這樣做是對的嗎

還有一點感覺以前也有這樣的狀況但沒有現在這麼誇張

app router下的route是透過你的folder directory來定義的

Nextjs已經告訴你這個架構長什麼樣子 也包括要用什麼檔案名稱

有page loading error 等等

可想而知你如果在IDE找page你會有一堆的page跑出來

我現在已經習慣search時候連那個route一起找要不然找不到

不方便的地方

雖然前面提說他們文檔還在改及更新是好事因為他們很努力的要確保不用有資訊的落差

但若去github issues看的話有時候會有修過的bug又跑出來的狀況

或是東西常常在改或不完善

我之前遇到一個bug是加上了basePath之後i18n就壞掉了 就不知道現在應該去哪一個route

先前文檔更新了cache的頁面講述Next有幾層cache能怎麼設定cache多久這樣

以文檔來說那篇寫得很好也滿清楚的

但Next因為要儘量讓效能很好 在很多地方有cache

有fetch data cache 有full route cache

有些cache是可以關掉的

但full route cache關不掉只能invalidate

這點我蠻討厭的

它本意是好的但沒有選擇可以關掉就很奇怪

加入我今天在route A 去了 route B

我如果比如更新了在route A也看得到data然後在沒有重新整理情況下去route A我會看到舊的東西

這個behavior是關不掉的

這對我來說很不方便

最後只能變成client component才行但那個體驗就不太一樣了

在錄音的這個時候 有些component不能寫單元測試因為會掛

比如server only component或是layout的metadata

不過他們在下一版會修復這個bug所以只能等了

結尾

你需要用嗎

對我來說如果這有解決你們產品的問題或是開發上的問題

team上面有足夠的能力去應付新技術帶來的risk

那你要用當然沒問題

我自己這樣摸下來

老實說我們的project不是很大就已經遇到好多問題了

或許這不適合我們的use case

或許這個Next app router還沒準備好

先從小project試試看有個感覺

我們是直接apollo graphql, tailwind 等等一次都下去感覺有點後悔但沒有這麼做我們project又起不來哈哈

今天先這樣啦也期待大家的分享

如果你喜歡這內容的話幫我在 Twitter 和 Threads 上面分享給其他正在前端這條路上努力的朋友們,也別忘了訂閱我們電子報收到第一手消息喔 🚀