py程式設計(三)課程網站
第 13 週 · 單元 5-1 · 換一套技術

Next.js(下):表單、測試、上線,以及兩種技術的比較

用 Server Action 完成新增評論與新增店家,部署到 Vercel,最後寫一份兩種技術的比較,作為期末專題選擇技術的依據。

W13Next.js表單+上線

本週結束時你會

今天的時間安排

0:00–0:45功能 3【跟著做】新增評論(Server Action+useActionState)
0:45–1:10功能 4【自己做】新增店家
1:10–1:20休息
1:20–1:45驗收:單元測試與手動測試
1:45–2:10上線:Vercel 匯入、設定 DATABASE_URL
2:10–2:30兩種技術比較、專案回顧

功能 3:新增評論【跟著做】

提示詞 Antigravity
請先讀 PROJECT.md。現在只做「新增評論」:
1. 把表單規則寫成 lib/validate.js 裡的純函式 validateReview(不碰資料庫),規則和 Flask 版完全相同:暱稱必填且最多 20 字、評分 1–5 的整數、短評最多 100 字
2. 在 lib/actions.js 寫 Server Action addReview:先呼叫 validateReview;有錯誤時回傳錯誤與使用者已輸入的內容;成功時用 $1 參數寫入資料庫、revalidatePath,再 redirect 回店家頁
3. 評論表單做成 Client Component,用 React 的 useActionState 顯示錯誤並保留已輸入的內容,送出中時按鈕停用
4. 用 Node.js 內建的 node:test 為 validateReview 寫單元測試,npm test 可以執行
只修改和這條功能相關的檔案。
輸入(在 /shop/1)正確結果(與第 5 週相同)
測試員、5 星★ 4.7(7 則評論),第一則是測試員
用開發者工具把選項改成 6 送出「評分必須是 1 到 5 的整數」,短評內容仍保留
暱稱空白、短評 101 字分別顯示對應的錯誤

為什麼要把規則抽成純函式:不碰資料庫的函式很好測試,執行一次不到一秒。Flask 版用 test_client 測整個網站;Next.js 版先把最容易出錯的規則用單元測試鎖住,網頁的部分再手動測試。

用開發者工具竄改選項時要注意:送出失敗後 React 會重新繪製表單,但被竄改過的 option 不一定會被還原。測試正確輸入前,請先重新整理頁面,否則看起來像「正確的評分也被擋下」。這是製作參考解答時實際遇到的狀況。

功能 4:新增店家【自己做】

輸入正確結果
測試咖哩、飯導向新店家頁,排行榜最後多一間尚無評分
派森牛肉湯、小吃「這家店已經在名單中了」
類別改成「火鍋」送出「請選擇類別」

測試完執行 npm run init-db 讓資料回到 12 間店、49 則評論。

上線:Next.js 部署到 Vercel

  1. 對 Antigravity 說「推上 GitHub。儲存庫名稱 foodie-next,Public。」,確認 .env.local 沒有被推上去。
  2. Vercel 匯入 foodie-next,Framework 會自動偵測為 Next.js。
  3. 到 Storage 把同一個 Neon 資料庫連到這個專案(Vercel 會設定 DATABASE_URL,預設使用 main 分支)。
  4. 在 Neon 的 SQL Editor 執行 db/schema.sql 與 db/seed.sql,然後重新部署。
應該看到Next.js 版的公開網址,排行榜與 Flask 版完全相同。

兩種技術比較

在 PROJECT.md 最後加一段「技術比較」,用你這兩個月的實際經驗填寫,期末專題選技術時會用到:

比較項目FlaskNext.js
同一條功能,誰的程式比較短?
出錯時,哪一個的錯誤訊息比較好懂?
測試好不好寫?
部署難度
AI 寫得比較穩的是哪一個?舉一個例子
期末專題我會選擇,原因是

沒有標準答案。常見的觀察:Flask 的資料流比較直觀,適合以表單與資料表為主的網站;Next.js 適合畫面互動多、需要即時更新的網站,但多了伺服器與瀏覽器之間的界線要理解。鼓勵學生依期末題目的性質選擇,而不是依喜好。

本週檢核

驗證紀錄:Next.js 參考解答(Next.js 15.5、React 19、Node.js 22)通過 10 項單元測試;排行榜、類別篩選、404、新增評論、竄改評分、重複店家,都已在瀏覽器實際操作並與 Flask 版的標準答案比對一致。