رفتن به محتوا

Nuxt 4.6: ‏nuxt/server مستقل از سرور، سشن‌های داخلی و $fetch تایپ‌شدهٔ بازنویسی‌شده

۵ دقیقه مطالعه
nuxt
nitro
typescript
vapor

Nuxt 4.6 بیشتر یک آماده‌سازی برای Nuxt 5 است تا یک انتشار پر از قابلیت. اعلامیهٔ رسمی آن را حول یک ایده روایت می‌کند: کد سرور نباید به جزئیات h3 و Nitro وابسته بماند. در کنار این ایده، سشن‌ها، بازنویسی $fetch تایپ‌شده، سازگاری با Vue Vapor و یک CLI جدید آمده است. صفحهٔ انتشار در GitHub تاریخ ۵ اکتبر را نشان می‌دهد؛ خود پست وبلاگ تاریخ مشخصی ندارد، پس من هم تاریخ دقیقی تثبیت نمی‌کنم.

nuxt/server: سطح سرور قابل‌حمل

تا امروز، روت‌های سرور توابعی مثل defineEventHandler و getQuery را معمولاً با auto-import از h3 می‌گرفتند. نسخهٔ 4.6 مسیر nuxt/server را به‌عنوان یک سطح import صریح و عمومی با تایپ‌های استاندارد وب اضافه می‌کند. طبق یادداشت‌های انتشار قرار است روی Nitro v2، Nitro v3 و @nuxt/vite-server آزمایشی کار کند.

ts
import { defineEventHandler, getQuery } from "nuxt/server";

export default defineEventHandler((event) => {
    const { name } = getQuery<{ name?: string }>(event);
    return { message: `Hello, ${name ?? "world"}!` };
});

نکتهٔ اصلی مسیر ارتقاست. طبق اعلامیه، Nuxt 5 به Nitro v3 و h3 v2 می‌رود. کدی که روی nuxt/server نوشته شود از این جهش بی‌اثر می‌ماند، اما کدی که مستقیم به h3 وابسته است اثر می‌پذیرد.

تغییرات رفتاری که باید بررسی کنید

یادداشت‌های انتشار چند تغییر را فهرست می‌کنند که در مهاجرت مهم‌اند:

  • defineEventHandler، getQuery و readBody که auto-import می‌شوند هنوز از h3 می‌آیند، ولی importهای صریح از nuxt/server API قابل‌حمل را می‌گیرند. ترکیب این دو در یک فایل خطای NUXT_E8012 می‌دهد.
  • sendRedirect حالا به‌جای ارسال، یک response برمی‌گرداند.
  • createError پارامترهای status و statusText را می‌گیرد.
  • هدرهای پاسخ از طریق event.res.headers تنظیم می‌شوند.

پس این فقط عوض کردن مسیر import نیست. هندلرهایی که ریدایرکت می‌فرستند یا هدر را دستی تنظیم می‌کنند به ویرایش واقعی نیاز دارند. مهاجرت را فایل‌به‌فایل انجام دهید، نه پوشه‌به‌پوشه، تا خطای import ترکیبی نگیرید.

سشن‌ها و appSecret

نسخهٔ 4.6 مقدار runtimeConfig.appSecret را معرفی می‌کند که با NUXT_APP_SECRET تنظیم می‌شود. طبق یادداشت‌های انتشار، در توسعه خودکار ساخته می‌شود و در production الزامی است. اعلامیه اضافه می‌کند که ماژول‌ها می‌توانند رازهای خودشان را از آن مشتق کنند.

روی آن، توابع سشن قرار دارند که داده را با iron درون یک کوکی مهر می‌کنند، پس ذخیره‌سازی سمت سرور لازم نیست:

ts
import { defineEventHandler, useSession } from "nuxt/server";

export default defineEventHandler(async (event) => {
    const session = await useSession<{ visits: number }>(event);
    await session.update((data) => ({ visits: (data.visits ?? 0) + 1 }));
    return { visits: session.data.visits };
});

مبادلاتی که پیش از جایگزین کردن یک کتابخانهٔ احراز هویت باید بسنجید:

  • سشن‌های کوکی مهرشده در مرورگر زندگی می‌کنند. محدودیت اندازهٔ کوکی اعمال می‌شود و بدون سازوکار اضافه (مثل denylist) نمی‌توانید یک سشن را سمت سرور باطل کنید.
  • احتمالاً چرخاندن NUXT_APP_SECRET سشن‌های موجود را باطل می‌کند. این را در صفحه‌هایی که خواندم صریح پیدا نکردم، پس پیش از تکیه کردن آزمایشش کنید.
  • الزام وجود آن در production یعنی استقرار بدون این متغیر با خطای آشکار شکست می‌خورد. پیش از ارتقا آن را به تنظیمات کانتینر یا پلتفرم اضافه کنید.

برای چیزهای کوچک مثل state گذرا، توکن‌های ضد CSRF یا ترجیحات سبک مناسب است. برای ورود، نقش‌ها و ابطال، یک بلوک سازنده است نه راه‌حل کامل.

$fetch تایپ‌شده، بازسازی‌شده روی fetchdts

$fetch تایپ‌شده با fetchdts بازطراحی شد. اعلامیه می‌گوید روش قبلی با رشد تعداد روت‌ها به محدودیت instantiation در TypeScript می‌خورد، و روش جدید با تعداد نقاط فراخوانی مقیاس می‌گیرد نه تعداد روت‌ها. همچنین body، query و headers را در زمان کامپایل با هندلر روت اعتبارسنجی می‌کند.

اعداد گزارش‌شده چشمگیرند: اپی با ۳٬۰۰۰ روت که قبلاً خطا می‌داد حالا type-check را در ۰٫۶۲ ثانیه تمام می‌کند، در برابر ۵۳٫۶۳ ثانیه قبلاً، و یادداشت‌های انتشار از کاهش ۱۲٫۸ میلیون instantiation به ۵۱ هزار برای ۱٬۰۰۰ روت می‌گویند. این‌ها اندازه‌گیری خود نویسندگان روی بار کاری خودشان است. ماشین، شکل پروژه و نسخهٔ TypeScript را پیدا نکردم، پس انتظار همین نسبت را روی اپ خود نداشته باشید. جهت کلی باورپذیر است: هزینهٔ تایپی که با نقاط فراخوانی رشد می‌کند شکل درستی برای مونوریپوهای بزرگ است، و زمان pnpm typecheck عددی است که خودتان می‌توانید قبل و بعد مقایسه کنید.

سازگاری با Vue Vapor

Nuxt حالا Vapor Mode در Vue 3.6 را به‌صورت interop پشتیبانی می‌کند، یعنی به‌جای بازنویسی اپ، به‌ازای هر کامپوننت فعالش می‌کنید. اعلامیه این سوییچ پیکربندی را نشان می‌دهد:

ts
export default defineNuxtConfig({
    vue: { vapor: true },
});

یادداشت‌های انتشار از نحو <script setup vapor> برای کامپوننت‌های منفرد هم نام می‌برند. Vue 3.6 در آخرین پستی که پوشش دادم هنوز در مرحلهٔ release candidate بود، پس این راهی برای آزمایش است، نه پیش‌فرضی که در یک اپ production روشن کنم. آن را پشت یک شاخه نگه دارید و اندازه بگیرید.

CLI v4 و خطاهای توسعه

Nuxt CLI v4 همراه آن می‌آید، با پنل تعاملی ترمینال که نشانی‌ها، پیشرفت راه‌اندازی و میانبرهای تک‌کلیدی را نشان می‌دهد. اعلامیه کاهش ۷۳٪ حجم نصب (از ۱۳٫۱ به ۳٫۵ مگابایت) و ۶٫۶ برابر سریع‌تر شدن اولین رندر رابط توسعه را گزارش می‌کند. خطاهای توسعه حالا به‌جای Youch از my-bad می‌گذرند، با stack trace نگاشته‌شده به سورس و code frame.

یادداشت‌های انتشار از یک سیستم افزونه برای useFetch و useAsyncData هم نام می‌برند که امکان افزودن گزینه و میان‌افزار سفارشی را بدون تحمیل نظر Nuxt می‌دهد. اگر دور این دو composable لایهٔ wrapper دارید، دفعهٔ بعد که به آن دست می‌زنید ارزش خواندن دارد.

ارتقا

  • نیازمندی جدید Node برابر ^22.22.3 || ^24.15.0 || >=26.0.0 است. پیش از هر چیز image در CI و پایهٔ کانتینر را بررسی کنید.
  • Nuxt 3 در ۳۱ ژوئیهٔ ۲۰۲۶ به پایان عمر رسید و Nuxt 2 و @nuxt/bridge دیگر پشتیبانی نمی‌شوند. nuxt init با npm create nuxt@latest جایگزین شده است.
  • با npx nuxt upgrade --dedupe ارتقا دهید.
  • برای پیش‌نمایش پیش‌فرض‌های Nuxt 5، پرچم سازگاری را تنظیم کنید:
ts
export default defineNuxtConfig({
    future: { compatibilityVersion: 5 },
});

ترتیب پیشنهادی من: بدون تغییر کد ارتقا دهید، نسخهٔ Node را درست کنید، سپس پرچم Nuxt 5 را روی یک شاخه روشن کنید و ببینید چه می‌شکند. بعد از آن هندلرهای سرور را فایل‌به‌فایل به nuxt/server مهاجرت دهید.

جمع‌بندی

اگر اپ شما چند روت سرور دارد، 4.6 یک ارتقای معمولی با بالا بردن Node است. اگر هندلرها یا ماژول‌های زیادی دارید که از h3 import می‌کنند، ارزش nuxt/server این است که هزینهٔ مهاجرت را یک بار و همین حالا در یک نسخهٔ minor می‌پردازید، نه هنگام جهش به Nitro v3. قابلیت سشن مفید ولی محدود است، و بازنویسی $fetch تایپ‌شده تغییری است که بیشترین احتمال را دارد در کدبیس‌های بزرگ بی‌صدا سود بدهد.

منابع