2023年8月31日 星期四

next.js初體驗小記

 在某些機緣巧合下開啟了第一次接觸Next.js,照官方指令創建專案第一感覺是:好慢!

說好的比vite快兩百倍呢==,我看他底層還是用webpack在打包,可能之前在講的打包工具還沒上線吧。

我用過Nuxt.js,一開始想說兩者屬於同樣性質的框架,使用上應該不會差太多吧,結果還真的差不多。因為網路上已經有很多文章說明Next.js的使用這邊就不再贅述。

這裡只想小小吐槽兩件事

第一點,只要有使用到事件的,基本上無法再server site被render,所以必須在專案最上方寫上“use client“,讓框架知道這個檔案只適用於client端渲染,但.....這是for檔案,如果我畫面上只有一個tag有事件觸發,我就必須把這個tag單獨用component包起來,並讓他在client端渲染,何其不方便,你看看人家Astro.js,當然這易受另外一個故事了。照這邏輯看起來,幾乎沒有頁面可以use server啊....這樣的設計到底為了什麼==


第二點,在Next.js框架是不能ajsx出去要資料的,會發生CORS,處理方式有兩個:

第一就是使用rewrites進行網址改寫達到proxy的效果

第二就是打自己的路由,例如我在/app/api/user/routes.ts寫入

export async function GET() {
return NextResponse.json(await useApi("contact").getList())
}
export async function POST(req: NextRequest) {
const { contact } = await req.json()
return NextResponse.json(await useApi("contact").create(contact))
}
export async function PATCH(req: NextRequest) {
const { id, info } = await req.json()
return NextResponse.json(await useApi("contact").update({ id, ...info }))
}
export async function DELETE(req: NextRequest) {
return NextResponse.json(await useApi("contact").delete({ id: req.nextUrl.searchParams.get("id")! }))
}

但這有個問題,如果api接收的params寫在網址上,例如/api/user/1,1在server這邊是讀不到的,真不知道是他NextRequest沒寫好還是怎樣,我知道有人會說要開個[變數]資料夾去接收變數,xxxx這我也試過了,router取params的變數這功能只存在client端。或是知道怎麼做的可以留言給我,總之我試了很久是找不到方法。

因為上述問題,所以client打的網址必須放在參數裡讓server讀到,變成/api/user?id=1,然後再由server放進params裡去打api,這也導致client跟server端打的網址可能會不一樣,但打自己,server在打出去,還有兩層邏輯....選這方法的人大概率不是蠢就是壞,這樣邏輯會四散各地,還要為client跟server寫兩次打api方法。

而且方法二執行起來,意思跟proxy差不多,所以理所當然我選擇了方法一。

兩天用下來我發現,或可真的可以好好學習一下Astro.js,MPA VS SPA之爭,可惜台灣學習資源很少。

Astro.js是最近才聽到的框架,好像也行之有年,也是ssr框架,然後也支援其他框架寫出來的component,所以可以進行整合。與以往SPA只有單一入口不同,會把不同pages最後分別導出成各自的index.html,撰寫邏輯跟api也都不難,有機會真的想要更深入研究一下

以上圖槽完Next.js心情舒服多了,來捆


html快取

快取大概是前端諸多夢魘之一吧,通常我們能做的有限,在現在打包軟體的加持下,js,css等檔案已經幾乎不可能有快取,因為後面會有hash,那唯一還是有可能被快取的檔案就是入口的index.html

今天又被客戶反應有快取,原本理智線已經快斷掉的我,突然被提醒meta能否設定一下讓html不要被快取,於是參考一下別人的網站列出下面四行

<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache" content="no-cache" />

就加一下,靜待日後觀察吧~