Nuxt 4.6 יצא יחד עם גרסה 4 של ה־CLI, ויש בו יותר שינויים ממה שמצופה מגרסה משנית. רובם שקטים: הם לא ישברו לכם כלום ביום השדרוג, אבל הם מכינים את הקרקע ל־Nuxt 5. במקום לעבור על הכול לפי הסדר, ריכזתי כאן את מה שלדעתי משנה בעבודה היומיומית, את מה ששווה רק להכיר, ואת המקומות שבהם השדרוג דורש תשומת לב.
הפוסט מבוסס על הכרזת הגרסה בבלוג של Nuxt. שם תמצאו את הרשימה המלאה, כולל המספרים וכל השינויים לכותבי מודולים. הבלוג הזה עצמו בנוי על Nuxt 4, אז חלק מהדוגמאות לקוחות ישירות מהקוד שלו.
לפני שמשדרגים: Node וה־CLI
שני שינויים יכולים לעצור את השדרוג עוד לפני שהקוד שלכם רץ:
- גרסת Node. הגרסה החדשה דורשת
^22.22.3,^24.15.0או26ומעלה. אם הפרויקט מקובע לגרסה ישנה יותר ב־.nvmrc, ב־Dockerfileאו ב־CI, עדכנו אותה קודם. כאן.nvmrcמצביע על 24.21, כך שאין בעיה. - ה־CLI החדש.
nuxt initהוסר, ופרויקט חדש פותחים עםnpm create nuxt@latest. התמיכה ב־Nuxt 2 וב־@nuxt/bridgeירדה מה־CLI.
השדרוג עצמו הוא פקודה אחת:
npx nuxt upgrade --dedupe
הדגל --dedupe מרענן את קובץ הנעילה, כדי שלא יישארו בו עותקים ישנים של חבילות פנימיות לצד החדשות. אחרי זה הריצו את הבדיקות ואת typecheck לפני כל דבר אחר.
nuxt/server: קוד שרת שלא תלוי בגרסת h3
זה השינוי שהכי מעניין אותי, כי הוא פותר בעיה שנתקלתי בה בבלוג הזה. Nuxt רץ היום על Nitro 2 ו־h3 1, אבל כלי פיתוח מושכים כבר את h3 2. התוצאה הייתה שבלי לקבע את h3 1 כתלות ישירה ב־package.json, TypeScript התחיל לקרוא את הטיפוסים של הגרסה הלא נכונה. כל קוד שרת שכתוב ישירות מול h3 קשור לגרסה מסוימת שלו.
Nuxt 4.6 מוסיף שכבה משלו: nuxt/server. היא מייצאת את הפונקציות המוכרות (defineEventHandler, getQuery, getRouterParam, readValidatedBody, createError ועוד) עם אובייקט RequestEvent אחיד, ואותו handler אמור לעבוד על Nitro 2, על Nitro 3 ועל בונה השרת הניסיוני מבוסס Vite.
// server/api/posts/[slug].get.ts
import { createError, defineEventHandler, getRouterParam } from 'nuxt/server'
export default defineEventHandler(async (event) => {
const slug = getRouterParam(event, 'slug')
const post = await findPost(slug)
if (!post) {
throw createError({ status: 404, statusText: 'Post not found' })
}
return post
})
שלוש מלכודות שכדאי להכיר לפני שמעבירים קוד:
- האימפורט המפורש הוא העיקר. הפונקציות שמגיעות דרך auto-import עדיין משתמשות בטיפוסים של h3. כדי לקבל את ה־API החדש צריך לייבא מ־
nuxt/serverבמפורש, וערבוב של שני הסוגים באותו קובץ מסתיים בשגיאהNUXT_E8012. createErrorמקבל שמות שדות אחרים:statusו־statusText, כמו ב־Fetch API.sendRedirectמחזיר תשובה במקום לשלוח אותה בעצמו, וכותרות קובעים דרךevent.res.headers.
אין חובה לעבור עכשיו. אבל קוד שרת חדש כדאי כבר לכתוב מול nuxt/server, כדי שהמעבר ל־Nitro 3 לא יהיה פרויקט בפני עצמו.
$fetch שבאמת בודק את הבקשה
$fetch ב־Nuxt ידע כבר קודם להסיק את סוג התשובה מנתיב ה־API. הגרסה החדשה בונה את המנגנון מחדש, עם מהדר בשם fetchdts, ובודקת גם את מה ששולחים: body, query ו־headers נבדקים מול ההגדרה של ה־handler בשרת. אם שיניתם שדה בצד השרת ושכחתם את הלקוח, typecheck יתפוס את זה.
בונוס פחות נוצץ אבל חשוב: לפי צוות Nuxt, בפרויקט עם 300 נתיבים מספר הטיפוסים ש־TypeScript צריך לחשב יורד ממיליונים לעשרות אלפים. בפרויקטים גדולים זה ההבדל בין עורך שמגיב מיד לבין עורך שחושב.
ב־Nuxt 4 זה עדיין בהפעלה ידנית (ב־Nuxt 5 זו תהיה ברירת המחדל):
// nuxt.config.ts
export default defineNuxtConfig({
experimental: {
routeTypedFetch: true,
},
})
סשנים מובנים ו־appSecret
עד עכשיו, סשן מבוסס cookie ב־Nuxt דרש מודול חיצוני או קוד ידני מול h3. עכשיו יש useSession() מובנה, ששומר את המידע ב־cookie חתום ומוצפן, בלי מסד נתונים בצד השרת.
הוא נשען על הגדרה חדשה, runtimeConfig.appSecret, שמגיעה ממשתנה הסביבה NUXT_APP_SECRET:
# .env (never commit the real value)
NUXT_APP_SECRET=a-long-random-string-of-at-least-32-characters
הסוד הזה הוא מה שמונע מגולש לזייף cookie, ולכן הוא שייך לסביבת הייצור ולא למאגר הקוד. מודולים יכולים לגזור ממנו סודות משלהם עם deriveSecret(purpose), כך שאין צורך להגדיר סוד נפרד לכל מודול.
חוויית פיתוח: CLI, שגיאות ודפי טעינה
אלה השינויים שתרגישו בדקה הראשונה אחרי השדרוג:
nuxt devמציג פאנל אינטראקטיבי בטרמינל: הכתובות, התקדמות העלייה, וקיצורים של מקש אחד.- שגיאות בזמן פיתוח מוצגות בשכבה חדשה, עם stack trace שממופה לקבצי המקור וקטע הקוד הרלוונטי. יש כפתור ״Copy error״, שימושי במיוחד כשמדביקים שגיאה לעוזר AI. גם שגיאת תחביר ב־
nuxt.config.tsמוצגת עכשיו כדף, שנטען מחדש כשמתקנים. - דף טעינה ודפי שגיאה חדשים, כולל 404 מעוצב מחדש.
- ה־CLI קטן ומהיר יותר: לפי ההכרזה, ההתקנה קטנה בכ־70% והמסך הראשון מופיע מהר פי כמה.
הקיצורים בפאנל:
| מקש | מה הוא עושה |
|---|---|
r | הפעלה מחדש של שרת הפיתוח |
o | פתיחת האתר בדפדפן |
l | הצגת הלוגים |
n | הצגת הבקשות שהגיעו לשרת |
p | הצגת הדפים באפליקציה |
ביצועים ו־payload קל יותר
כמה שיפורים עובדים בלי שתעשו כלום, וכמה דורשים הפעלה:
<NuxtLink>מתרנדר בשרת כ־<a>פשוט. לפי ההכרזה, זה לבד מעלה את קצב ה־SSR בכרבע.useCookieמפענח את ה־cookies פעם אחת לכל בקשה, ו־cookie שנקבע במהלך ה־SSR נקרא נכון בקריאות הבאות.experimental.early404מחזיר 404 לנתיב שלא קיים בלי ליצור בכלל את אפליקציית Vue. שימושי מול בוטים שסורקים כתובות אקראיות.serialize: falseב־useFetchוב־useAsyncDataמשאיר נתונים מחוץ ל־payload, כשאין צורך בהם בצד הלקוח. בזמן פיתוח תקבלו גם אזהרה כשה־payload עובר 100kB.
ויש גם יכולת חדשה לבנות ״תוספים״ ל־useFetch ול־useAsyncData, עם defineUseFetchAddon ו־defineUseAsyncDataAddon: התנהגות כמו רענון כשהחלון חוזר לפוקוס, polling או ניסיון חוזר, שמגדירים פעם אחת ומשתמשים בה בכל מקום.
לאתר סטטי כמו הבלוג הזה, הדבר המעניין ביותר הוא experimental.prerenderErrorPages: הוא מייצר בזמן הבנייה קובץ 404.html אמיתי. כאן nginx כבר מגיש 404.html עם סטטוס 404, אז זה מקום שאבדוק בשדרוג.
ניסויים: מה שווה להכיר, לא להפעיל בייצור
שלושה דברים בגרסה מסומנים בבירור כניסיוניים. שווה לנסות אותם בענף צדדי, לא בפרויקט של לקוח:
- Vue Vapor. מצב קומפילציה של Vue בלי Virtual DOM. ב־Nuxt 4.6 מפעילים אותו עם
vue.vapor: true, ואז כל קומפוננטה בוחרת בעצמה, עם<script setup vapor>. דורש Vue3.6בגרסת RC. - בונה שרת מבוסס Vite (
@nuxt/vite-server), שמופעל עםserver.builder: 'vite'. הוא תומך ב־SPA, ב־SSR עם Node, ב־handlers בסגנון Fetch (Cloudflare, Netlify) ובבנייה סטטית, אבל בלי חלק מהיכולות של Nitro, כמו storage ו־tasks. - תצוגה מקדימה של Nuxt 5 עם
future.compatibilityVersion: 5. זה מפעיל בבת אחת דפים עם טיפוסים,$fetchעם טיפוסים, ניתוב רגיש לאותיות גדולות וקטנות, וכמה שינויים נוספים. זו הדרך הטובה ביותר לגלות מה יישבר במעבר ל־Nuxt 5, כל עוד יש זמן לתקן.
אם הייתי משדרג היום
- 01Node קודם
בדקו את גרסת Node ב־.nvmrc, ב־Dockerfile וב־CI, ועדכנו אם צריך.
- 02שדרוג ובדיקות
npx nuxt upgrade --dedupe, ואחריו test, typecheck ובנייה מלאה.
- 03קוד שרת חדש
handlers חדשים נכתבים מול nuxt/server, עם אימפורט מפורש.
- 04ענף לניסויים
routeTypedFetch ו־compatibilityVersion 5 בענף צדדי, כדי לראות מה Nuxt 5 ידרוש.
הפוסט מבוסס על הכרזת Nuxt 4.6 בבלוג של Nuxt. הבחירה, הסדר, הדוגמאות וההמלצות הם שלי. לרשימה המלאה של השינויים, ובמיוחד לכותבי מודולים, כדאי לקרוא את ההכרזה ואת מדריך השדרוג.