ارتقا از Next.js 15 به 16؛ چکلیست تغییرات شکننده و آزمون پس از مهاجرت
برای ارتقای پروژه Next.js 15 به 16، پیشنیازها، تغییرات Proxy و APIهای ناهمگام، Turbopack، تصویر و کش را مرحلهبهمرحله بررسی کنید و با سناریوی آزمون جلوی خطای انتشار را بگیرید.
ارتقای یک پروژه واقعی از Next.js 15 به 16 با عوضکردن یک عدد در package.json تمام نمیشود. ممکن است برنامه در محیط توسعه باز شود، اما در build تولیدی به پیکربندی bundler، دسترسی همزمان به params یا مسیر تصویر وابسته باشد. در این راهنما، مهاجرت را به چند دروازه کوچک تقسیم میکنیم تا هر تغییر یک نتیجه قابلسنجش و یک راه بازگشت داشته باشد. هدف، انتشار امن پروژه موجود است؛ نه بازنویسی بیدلیل همه صفحهها.
پیش از ارتقا: خط مبنا و راه بازگشت
اول روی شاخهای جدا از شاخه انتشار کار کنید. نسخه فعلی Next.js، React، Node.js و TypeScript، مدیر بسته و فایل lock را ثبت کنید. یک build تمیز از نسخه 15 و نتیجه آزمونهای فعلی بگیرید؛ اگر همین نسخه خطا دارد، بعد از ارتقا تشخیص منشأ خطا دشوار میشود. مسیرهای حساس مثل ورود، صفحه پویا، فرم، تصویر و API را فهرست کنید. برای هرکدام نشانی، ورودی نمونه و رفتار مورد انتظار بنویسید. از داده حساس واقعی برای آزمون استفاده نکنید.
طبق راهنمای رسمی ارتقای Next.js 16، حداقل Node.js نسخه 20.9 و TypeScript نسخه 5.1 است. پیش از تغییر بستهها، محیط توسعه، CI و سرور را جداگانه با این پیشنیازها مقایسه کنید. عبور لپتاپ از شرط نسخه، به معنی آمادهبودن محیط استقرار نیست. فایل lock و تنظیمات CI را در همان شاخه نگه دارید تا برگشت به نسخه قبلی تنها به حافظه فردی وابسته نباشد.
یک سناریوی کوچک برای آزمون
فرض کنید برنامه شما صفحه /blog/[slug]، یک مسیر ورود با middleware.ts و تصاویر محلی با پارامتر نسخه دارد. پیش از ارتقا، یک URL مقاله موجود و یک URL ناموجود را ثبت کنید؛ از نقش مهمان و کاربر واردشده خروجی مورد انتظار بگیرید؛ و یک تصویر معمولی و یک تصویر با query string را باز کنید. همین چند مورد، پس از ارتقا به آزمون بازگشت قابلتکرار تبدیل میشوند. این سناریو نمونه است و نتیجهای از اجرای واقعی روی پروژه شما ادعا نمیکند.
دروازه اول: codemod، نه ویرایش کورکورانه
راهنمای رسمی برای نسخه 16 از codemod ارتقا استفاده میکند. اجرای آن میتواند برخی تغییرات شناختهشده، از جمله جابهجایی پیکربندی Turbopack، تبدیل قرارداد middleware به proxy و حذف گزینههای قدیمی را انجام دهد. پیش از اجرا وضعیت Git را ثبت و پس از اجرا diff را فایلبهفایل بخوانید؛ خروجی خودکار جای بازبینی منطق پروژه را نمیگیرد. اگر وابستگیهای پروژه به نسخههای خاص قفل شدهاند، تغییر نسخه React و type packageها را نیز همراه با خروجی نصب بررسی کنید.
در این مرحله فقط مهاجرت پایه را هدف بگیرید. فعالکردن Cache Components، تغییر معماری داده و نوسازی همه تصویرها را همزمان انجام ندهید. اگر هر چند تغییر مستقل در یک commit مخلوط شوند، هم عیبیابی سختتر میشود و هم rollback ممکن است کار سالم را برگرداند. پس از هر گروه تغییر، نصب، typecheck و build را طبق اسکریپتهای واقعی همان مخزن اجرا کنید؛ نام اسکریپتها در پروژهها یکسان نیست.
دروازه دوم: middleware به proxy و مرز اجرا
در Next.js 16 نام قرارداد middleware.ts به proxy.ts تغییر کرده و نام تابع خروجی نیز میتواند proxy باشد. مستندات Proxy میگوید این قرارداد در runtime مبتنی بر Node.js اجرا میشود؛ بنابراین موضوع فقط تغییر نام فایل نیست. اگر کد قدیمی به Edge runtime یا محدودیتهای آن وابسته بوده، آن وابستگی را پیش از تغییر بررسی کنید. اگر برای همه درخواستها کار سنگین یا فراخوانی خارجی در middleware داشتهاید، فرصت خوبی است ضرورت آن را دوباره بسنجید.
بعد از تغییر، matcherها را با مثال واقعی آزمون کنید: آیا مسیر محافظتشده هنوز ریدایرکت میشود؟ آیا صفحه عمومی اشتباهاً گیر نمیافتد؟ آیا داراییهای استاتیک یا API از الگوی matcher ناخواسته عبور میکنند؟ پاسخ را از رفتار مرورگر و لاگ سرور بگیرید، نه فقط از موفقیت کامپایل. برای تیمی که چند محیط دارد، تفاوت رفتار dev و محیط مشابه Production را ثبت کنید.
دروازه سوم: APIهای درخواست ناهمگام
در نسخه 15 برای بعضی APIهای درخواست، سازگاری موقت دسترسی همزمان وجود داشت؛ راهنمای نسخه 16 توضیح میدهد که این سازگاری حذف شده است. فراخوانیهای cookies()، headers() و draftMode() و دسترسی به params یا searchParams در محلهای مستند را جستوجو کنید. اگر کد به شکل همزمان نتیجه را میخواند، آن را متناسب با قرارداد Promise تغییر دهید. برای تایپهای route نیز راهنمای رسمی تولید type helper را ارائه میکند.
تمرکز آزمون باید روی مسیرهای پویا باشد: slug معتبر و نامعتبر، query خالی و چندمقداری، و صفحهای که از header یا cookie برای پاسخ استفاده میکند. اگر صفحه فقط با داده توسعهدهنده کار میکند، آزمون یک ورودی دیگر لازم است؛ خطاهای Promise ممکن است فقط در شاخه کمتر دیدهشده ظاهر شوند. فایلهای تولید تصویر متادیتا مانند opengraph-image را فراموش نکنید، چون قرارداد بعضی آرگومانهای آنها نیز در نسخه 16 تغییر کرده است.
دروازه چهارم: Turbopack و build تولیدی
در Next.js 16، Turbopack برای next dev و next build پیشفرض است. اگر مخزن پیکربندی سفارشی Webpack دارد، build ممکن است برای جلوگیری از نادیدهگرفتن خاموش آن متوقف شود. چنین توقفی را با حذف شتابزده تنظیمات حل نکنید: ابتدا مشخص کنید کدام loader، alias یا رفتار build واقعاً لازم است. راهنمای رسمی برای ارزیابی موقت مسیر build با Webpack را نیز توضیح میدهد؛ اما این راه میانبُر را بهعنوان مهاجرت کامل bundler گزارش نکنید.
دو خروجی را جداگانه ببینید: توسعه محلی و build تولیدی. در پروژهای با CSS، فایلهای Sass، importهای غیرمعمول یا افزونه build، رفتار هر دو ممکن است تفاوت داشته باشد. یک صفحه اصلی، یک صفحه پویا و یک مسیر خطا را پس از build در محیط نزدیک به Production باز کنید. اگر هنوز از گزینه قدیمی next lint استفاده میکنید، توجه کنید که نسخه 16 آن را حذف کرده و build نیز لاینت را خودکار اجرا نمیکند؛ طبق راهنمای نصب، لاینت را بهصورت گام مستقل CI نگه دارید.
دروازه پنجم: تصویر، کش و رفتار داده
در تغییرات next/image، منبع محلیِ دارای query string به تنظیم مناسب images.localPatterns.search نیاز دارد. اگر پروژه برای cache-busting از نشانیهایی مانند /assets/photo?v=1 استفاده میکند، همان URL را پس از ارتقا باز و خطای بهینهسازی تصویر را بررسی کنید. در نسخه 16 مقدار پیشفرض images.minimumCacheTTL و بعضی پیشفرضهای کیفیت و اندازه نیز تغییر کردهاند. برای تصاویر حساس، فقط دیدن تگ HTML کافی نیست؛ درخواست تصویر واقعی، هدر و نتیجه بصری را بررسی کنید.
Cache Components قابلیت اختیاری است، نه پیششرط بالا آمدن نسخه 16. اگر امروز صفحهها با مدل کش قبلی کار میکنند، ابتدا مهاجرت پایه را تثبیت کنید. سپس در یک تغییر مستقل درباره فعالسازی cacheComponents و کاربرد use cache تصمیم بگیرید. برای محتوایی که باید تازه باشد، رفتار پیشنمایش، انتشار و invalidation را با ورودی مشخص بسنجید؛ برچسب «سریعتر» بدون اندازهگیری پروژه خودتان نتیجه آزمون نیست.
چکلیست آزمون پیش از استقرار
- نسخههای Node.js و TypeScript در دستگاه، CI و سرور با حداقلهای رسمی سازگار باشند.
- diff مربوط به codemod خوانده شود و تغییرهای دستی و خودکار در commitهای قابلبرگشت مشخص باشند.
- build تولیدی، typecheck، لاینت مستقل و آزمونهای موجود همگی جدا اجرا و نتیجهشان ثبت شوند.
- یک route پویا با slug معتبر و نامعتبر، و یک route با searchParams آزمون شود.
- مسیرهای ورود، خروج، ریدایرکت و matcher در Proxy برای مهمان و کاربر مجاز بررسی شوند.
- تصاویر محلی معمولی و دارای query string در مرورگر و پاسخ شبکه کنترل شوند.
- صفحههای وابسته به داده تازه، رفتار کش و نمایش پس از تغییر محتوا را نشان دهند.
- در محیط پیشنمایش، مسیرهای کلیدی و خطاها با همان ورودیهای خط مبنا مقایسه شوند.
- زمان و روش rollback، نسخه lockfile و مسئول تصمیم انتشار پیش از رفتن به Production روشن باشد.
جدول تصمیم بدون پیچیدگی اضافی
برای هر خطا سه چیز بنویسید: نشانی یا گام بازتولید، تغییر مرتبط در نسخه 16 و معیار رفع. مثال: «تصویر محلی با query string خطا میدهد» را به تنظیم localPatterns و آزمون درخواست همان فایل وصل کنید. «صفحه پویا خطا میدهد» را به محل استفاده از params و آزمون یک slug مشخص وصل کنید. اگر علت با یک تغییر مستند روشن نشد، آن را در دسته نیازمند بررسی نگه دارید؛ حدس را جای نتیجه ننشانید.
- خطای محیط: نسخه runtime یا تنظیم CI را پیش از کد بررسی کنید.
- خطای کامپایل: diff codemod و APIهای حذفشده را با راهنمای رسمی تطبیق دهید.
- خطای فقط Production: bundler، متغیرهای محیط و مسیرهای بهینهسازی تصویر را مقایسه کنید.
- خطای رفتاری: سناریوی خط مبنا را با همان داده در پیشنمایش تکرار کنید.
پرسشهای متداول
آیا باید Cache Components را همزمان فعال کنم؟
خیر. این قابلیت اختیاری است. نخست ناسازگاریهای ارتقای نسخه را رفع کنید و بعد مهاجرت مدل کش را بهعنوان تغییر جداگانه با معیار تازهبودن داده و عملکرد بسنجید.
آیا تغییر middleware به proxy فقط تغییر نام است؟
نام فایل و تابع تغییر میکند، اما runtime Proxy مبتنی بر Node.js است. matcher و وابستگی به Edge را روی مسیرهای واقعی بازبینی کنید.
آیا build موفق به معنی آمادگی انتشار است؟
خیر. مسیرهای پویا، احراز هویت، تصویر و کش را با نمونه ورودی مشخص در محیط پیشنمایش بررسی کنید؛ لاینت نیز در نسخه 16 گام جداگانه است.
با پیکربندی سفارشی Webpack چه کنیم؟
نخست وابستگی واقعی را شناسایی کنید. اگر لازم است موقتاً با Webpack build بگیرید، نتیجه را بهعنوان ارزیابی موقت ثبت کنید و سازگاری Turbopack را جدا حل کنید.
جمعبندی و گام بعدی
ارتقای Next.js 15 به 16 زمانی قابلاعتماد است که از «نسخه نصب شد» به «رفتار حیاتی با ورودی مشخص تأیید شد» برسید. پیشنیازها، Proxy، APIهای ناهمگام، Turbopack و تصویر را یکییکی بررسی کنید و فعالسازی Cache Components را از ارتقای پایه جدا نگه دارید. پس از گذر از چکلیست، پیشنمایش و روش بازگشت را به تیم تحویل دهید. برای مرحله انتشار و بررسی Preview، دامنه و rollback نیز راهنمای استقرار Next.js روی Vercel را ببینید.
پیش از ارتقای پروژه اصلی، همین چکلیست را روی یک شاخه جدا اجرا کنید و نتیجه build، مسیرهای حیاتی و راه بازگشت را ثبت کنید.