Backالعودة إلى المدونة

الإصدار المرشح لـ Next.js 15 (RC)

أصبح الإصدار المرشح (RC) لـ Next.js 15 متاحًا الآن. هذه النسخة المبكرة تتيح لك اختبار أحدث الميزات قبل الإصدار المستقر القادم.

أصبح الإصدار المرشح (RC) لـ Next.js 15 متاحًا الآن. هذه النسخة المبكرة تتيح لك اختبار أحدث الميزات قبل الإصدار المستقر القادم.

جرب Next.js 15 RC اليوم:

Terminal
npm install next@rc react@rc react-dom@rc

React 19 RC

تم بناء موجه تطبيق Next.js على قناة كاناري الخاصة بـ React للإطارات، مما سمح للمطورين باستخدام هذه الواجهات البرمجية الجديدة لـ React وتقديم الملاحظات عليها قبل إصدار v19.

يدعم Next.js 15 RC الآن React 19 RC، والذي يتضمن ميزات جديدة لكل من العميل والخادم مثل الإجراءات (Actions).

اقرأ دليل الترقية إلى Next.js 15، ودليل الترقية إلى React 19، وشاهد محاضرة React Conf الرئيسية لمعرفة المزيد.

ملاحظة: بعض المكتبات الخارجية قد لا تكون متوافقة مع React 19 بعد.

مجمّع React (تجريبي)

مجمّع React هو مجمع تجريبي جديد تم إنشاؤه بواسطة فريق React في Meta. يفهم المجمع التعليمات البرمجية الخاصة بك على مستوى عميق من خلال فهمه لمعاني JavaScript العادية وقواعد React، مما يسمح له بإضافة تحسينات تلقائية للتعليمات البرمجية الخاصة بك. يقلل المجمع من كمية الحفظ اليدوي الذي يتعين على المطورين القيام به من خلال واجهات برمجة التطبيقات مثل useMemo وuseCallback - مما يجعل التعليمات البرمجية أبسط وأسهل في الصيانة وأقل عرضة للأخطاء.

مع Next.js 15، أضفنا دعمًا لـمجمّع React.

قم بتثبيت babel-plugin-react-compiler:

Terminal
npm install babel-plugin-react-compiler

ثم أضف خيار experimental.reactCompiler في next.config.js:

next.config.ts
const nextConfig = {
  experimental: {
    reactCompiler: true,
  },
};
 
module.exports = nextConfig;

اختياريًا، يمكنك تكوين المجمع للعمل في وضع "الاشتراك الاختياري" كما يلي:

next.config.ts
const nextConfig = {
  experimental: {
    reactCompiler: {
      compilationMode: 'annotation',
    },
  },
};
 
module.exports = nextConfig;

ملاحظة: حاليًا، يمكن استخدام مجمع React في Next.js فقط من خلال ملحق Babel، مما قد يؤدي إلى أوقات بناء أبطأ.

تعرف على المزيد حول مجمّع React، وخيارات تكوين Next.js المتاحة.

تحسينات أخطاء الترطيب

قام Next.js 14.1 بتحسينات في رسائل الأخطاء وأخطاء الترطيب. يواصل Next.js 15 البناء على ذلك من خلال إضافة عرض محسن لأخطاء الترطيب. تعرض أخطاء الترطيب الآن التعليمات البرمجية المصدر للخطأ مع اقتراحات حول كيفية معالجة المشكلة.

على سبيل المثال، كانت هذه رسالة خطأ ترطيب سابقة في Next.js 14.1:

رسالة خطأ الترطيب في Next.js 14.1

قام Next.js 15 RC بتحسين هذا إلى:

رسالة خطأ الترطيب المحسنة في Next.js 15 RC

تحديثات التخزين المؤقت

تم إطلاق موجه تطبيق Next.js مع إعدادات افتراضية للتخزين المؤقت. تم تصميم هذه الإعدادات لتوفير الخيار الأكثر أداءً افتراضيًا مع القدرة على الانسحاب عند الحاجة.

بناءً على ملاحظاتكم، قمنا بإعادة تقييم استدلالات التخزين المؤقت الخاصة بنا وكيفية تفاعلها مع مشاريع مثل التصيير الجزئي المسبق (PPR) ومع المكتبات الخارجية التي تستخدم fetch.

مع Next.js 15، نقوم بتغيير الإعداد الافتراضي للتخزين المؤقت لطلبات fetch، ومعالجات مسار GET، وتخزين موجه العميل من مخزن مؤقت افتراضيًا إلى غير مخزن مؤقت افتراضيًا. إذا كنت ترغب في الاحتفاظ بالسلوك السابق، يمكنك الاستمرار في اختيار التخزين المؤقت.

سنواصل تحسين التخزين المؤقت في Next.js في الأشهر القادمة وسنشارك المزيد من التفاصيل في إعلان Next.js 15 GA.

طلبات fetch لم تعد مخزنة مؤقتًا افتراضيًا

يستخدم Next.js خيار التخزين المؤقت في واجهة برمجة تطبيقات fetch على الويب لتكوين كيفية تفاعل طلب fetch من جانب الخادم مع ذاكرة التخزين المؤقت HTTP الدائمة للإطار:

fetch('https://...', { cache: 'force-cache' | 'no-store' });
  • no-store - جلب مورد من خادم بعيد في كل طلب وعدم تحديث ذاكرة التخزين المؤقت
  • force-cache - جلب مورد من ذاكرة التخزين المؤقت (إذا كان موجودًا) أو من خادم بعيد وتحديث ذاكرة التخزين المؤقت

في Next.js 14، تم استخدام force-cache افتراضيًا إذا لم يتم توفير خيار cache، إلا إذا تم استخدام دالة ديناميكية أو خيار تكوين ديناميكي.

في Next.js 15، يتم استخدام no-store افتراضيًا إذا لم يتم توفير خيار cache. هذا يعني أن طلبات fetch لن يتم تخزينها مؤقتًا افتراضيًا.

لا يزال بإمكانك اختيار تخزين طلبات fetch مؤقتًا عن طريق:

معالجات مسار GET لم تعد مخزنة مؤقتًا افتراضيًا

في Next.js 14، كانت معالجات المسار التي تستخدم طريقة HTTP GET مخزنة مؤقتًا افتراضيًا ما لم تستخدم دالة ديناميكية أو خيار تكوين ديناميكي. في Next.js 15، لا يتم تخزين دوال GET مؤقتًا افتراضيًا.

لا يزال بإمكانك اختيار التخزين المؤقت باستخدام خيار تكوين مسار ثابت مثل export dynamic = 'force-static'.

تبقى معالجات المسار الخاصة مثل sitemap.ts، وopengraph-image.tsx، وicon.tsx، وملفات البيانات الوصفية الأخرى ثابتة افتراضيًا ما لم تستخدم دوال ديناميكية أو خيارات تكوين ديناميكية.

ذاكرة التخزين المؤقت لموجه العميل (Client Router Cache) لم تعد تخزن مكونات الصفحة افتراضيًا

في إصدار Next.js 14.2.0، قدمنا علامة تجريبية staleTimes للسماح بتكوين مخصص لـذاكرة التخزين المؤقت للموجه (Router Cache).

في Next.js 15، لا تزال هذه العلامة متاحة، لكننا نغير السلوك الافتراضي ليصبح staleTime بقيمة 0 لمقاطع الصفحة. هذا يعني أنه أثناء التنقل في تطبيقك، سيعكس العميل دائمًا أحدث البيانات من مكون(ات) الصفحة التي تصبح نشطة كجزء من عملية التنقل. ومع ذلك، هناك سلوكيات مهمة لا تزال كما هي:

  • لن يتم إعادة جلب بيانات التخطيط المشتركة من الخادم لمواصلة دعم التصيير الجزئي (Partial Rendering).
  • سيستمر التنقل للخلف/الأمام في الاستعادة من ذاكرة التخزين المؤقت لضمان قدرة المتصفح على استعادة موضع التمرير.
  • سيظل Loading.js مخزنًا مؤقتًا لمدة 5 دقائق (أو قيمة التكوين staleTimes.static).

يمكنك اختيار سلوك ذاكرة التخزين المؤقت السابقة لموجه العميل عن طريق تعيين التكوين التالي:

next.config.ts
const nextConfig = {
  experimental: {
    staleTimes: {
      dynamic: 30,
    },
  },
};
 
module.exports = nextConfig;

التبني التدريجي للتصيير المسبق الجزئي (Partial Prerendering) (تجريبي)

في Next.js 14، قدمنا التصيير المسبق الجزئي (PPR) - تحسين يجمع بين التصيير الثابت والديناميكي في نفس الصفحة.

يستخدم Next.js حاليًا التصيير الثابت افتراضيًا ما لم تستخدم وظائف ديناميكية مثل cookies(), headers()، وطلبات البيانات غير المخزنة مؤقتًا. واجهات برمجة التطبيقات هذه تجعل المسار بأكمله يستخدم التصيير الديناميكي. مع PPR، يمكنك تغليف أي واجهة مستخدم ديناميكية في حدود Suspense. عند وصول طلب جديد، سيقدم Next.js على الفور قشرة HTML ثابتة، ثم يعرض ويبث الأجزاء الديناميكية في نفس طلب HTTP.

للسماح بالتبني التدريجي، أضفنا خيار تكوين مسار experimental_ppr لاختيار تخطيطات وصفحات محددة لاستخدام PPR:

app/page.jsx
import { Suspense } from "react"
import { StaticComponent, DynamicComponent } from "@/app/ui"
 
export const experimental_ppr = true
 
export default function Page() {
  return {
     <>
	     <StaticComponent />
	     <Suspense fallback={...}>
		     <DynamicComponent />
	     </Suspense>
     </>
  };
}

لاستخدام الخيار الجديد، ستحتاج إلى تعيين تكوين experimental.ppr في ملف next.config.js إلى 'incremental':

next.config.ts
const nextConfig = {
  experimental: {
    ppr: 'incremental',
  },
};
 
module.exports = nextConfig;

بمجرد تمكين PPR لجميع المقاطع، سيعتبر آمنًا لك تعيين قيمة ppr إلى true، وتمكينه للتطبيق بأكمله وجميع المسارات المستقبلية.

سنشارك المزيد حول خارطة طريق PPR في منشور مدونة Next.js 15 GA.

تعلم المزيد عن التصيير المسبق الجزئي (Partial Prerendering).

تنفيذ التعليمات البرمجية بعد الاستجابة باستخدام next/after (تجريبي)

عند معالجة طلب المستخدم، يقوم الخادم عادةً بمهام مرتبطة مباشرة بحساب الاستجابة. ومع ذلك، قد تحتاج إلى تنفيذ مهام مثل التسجيل، والتحليلات، ومزامنة أنظمة خارجية أخرى.

نظرًا لأن هذه المهام ليست مرتبطة مباشرة بالاستجابة، لا يجب أن يضطر المستخدم إلى انتظار اكتمالها. يؤجل العمل بعد الرد على المستخدم تحديًا لأن وظائف الخادم (serverless) تتوقف عن الحساب فور إغلاق الاستجابة.

after() هي واجهة برمجة تطبيقات تجريبية جديدة تحل هذه المشكلة عن طريق السماح لك بجدولة العمل ليتم معالجته بعد انتهاء بث الاستجابة، مما يتيح للمهام الثانوية التشغيل دون عرقلة الاستجابة الأساسية.

لاستخدامها، أضف experimental.after إلى next.config.js:

next.config.ts
const nextConfig = {
  experimental: {
    after: true,
  },
};
 
module.exports = nextConfig;

ثم استورد الوظيفة في مكونات الخادم (Server Components)، أو إجراءات الخادم (Server Actions)، أو معالجات المسار (Route Handlers)، أو البرمجيات الوسيطة (Middleware).

import { unstable_after as after } from 'next/server';
import { log } from '@/app/utils';
 
export default function Layout({ children }) {
  // مهمة ثانوية
  after(() => {
    log();
  });
 
  // مهمة أساسية
  return <>{children}</>;
}

تعلم المزيد عن next/after.

تحديثات create-next-app

لـ Next.js 15، قمنا بتحديث create-next-app بتصميم جديد.

تصميم جديد لـ create-next-app في Next.js 15 RC

عند تشغيل create-next-app، هناك مطالبة جديدة تسأل إذا كنت تريد تمكين Turbopack للتطوير المحلي (الافتراضي هو No).

Terminal
 هل ترغب في استخدام Turbopack لـ next dev؟ لا / نعم

يمكن استخدام علامة --turbo لتمكين Turbopack.

Terminal
npx create-next-app@rc --turbo

لتسهيل بدء مشروع جديد، تمت إضافة علامة --empty جديدة إلى واجهة سطر الأوامر. سيؤدي هذا إلى إزالة أي ملفات وأنماط غير ضرورية، مما ينتج عنه صفحة "مرحبًا بالعالم" بسيطة.

Terminal
npx create-next-app@rc --empty

تحسين حزم الحزم الخارجية (مستقر)

يمكن أن يؤدي تجميع الحزم الخارجية إلى تحسين أداء بدء التشغيل البارد لتطبيقك. في موجه التطبيق (App Router)، يتم تجميع الحزم الخارجية افتراضيًا، ويمكنك استثناء حزم محددة باستخدام خيار التكوين الجديد serverExternalPackages.

في موجه الصفحات (Pages Router)، لا يتم تجميع الحزم الخارجية افتراضيًا، ولكن يمكنك تقديم قائمة بالحزم لتجميعها باستخدام خيار transpilePackages الموجود. مع خيار التكوين هذا، تحتاج إلى تحديد كل حزمة.

لتوحيد التكوين بين موجه التطبيق وموجه الصفحات، نقدم خيارًا جديدًا، bundlePagesRouterDependencies لمطابقة التجميع التلقائي الافتراضي لموجه التطبيق. يمكنك بعد ذلك استخدام serverExternalPackages لاستثناء حزم محددة، إذا لزم الأمر.

next.config.ts
const nextConfig = {
  // تجميع الحزم الخارجية تلقائيًا في موجه الصفحات:
  bundlePagesRouterDependencies: true,
  // استثناء حزم محددة من التجميع لكل من موجه التطبيق وموجه الصفحات:
  serverExternalPackages: ['package-name'],
};
 
module.exports = nextConfig;

تعلم المزيد عن تحسين الحزم الخارجية.

تغييرات أخرى

  • [تغيير رئيسي] الحد الأدنى لإصدار React هو الآن 19 RC
  • [تغيير رئيسي] next/image: تمت إزالة squoosh لصالح sharp كاعتماد اختياري (PR)
  • [تغيير رئيسي] next/image: تغيير Content-Disposition الافتراضي إلى attachment (PR)
  • [تغيير رئيسي] next/image: خطأ عندما يحتوي src على مسافات بادئة أو لاحقة (PR)
  • [تغيير رئيسي] البرمجيات الوسيطة (Middleware): تطبيق شرط react-server للحد من استيراد واجهات برمجة تطبيقات React غير الموصى بها (PR)
  • [تغيير رئيسي] next/font: إزالة دعم الحزمة الخارجية @next/font (PR)
  • [تغيير رئيسي] next/font: إزالة تجزئة font-family (PR)
  • [تغيير رئيسي] التخزين المؤقت: سيؤدي force-dynamic الآن إلى تعيين افتراضي no-store لذاكرة التخزين المؤقت للجلب (PR)
  • [تغيير رئيسي] التكوين: تمكين swcMinify (PR), missingSuspenseWithCSRBailout (PR), و outputFileTracing (PR) افتراضيًا وإزالة الخيارات المهملة
  • [تغيير رئيسي] إزالة التتبع التلقائي لـ Speed Insights (يجب الآن استخدام الحزمة المخصصة @vercel/speed-insights) (PR)
  • [تغيير رئيسي] إزالة امتداد .xml لمسارات خريطة الموقع (sitemap) الديناميكية ومحاذاة عناوين URL لخريطة الموقع بين التطوير والإنتاج (PR)
  • [تحسين] البيانات الوصفية (Metadata): تحديث متغيرات البيئة الاحتياطية لـ metadataBase عند الاستضافة على Vercel (PR)
  • [تحسين] إصلاح إزالة الشجرة (tree-shaking) مع استيرادات مختلطة من مساحة الاسم والاستيرادات المسماة من optimizePackageImports (PR)
  • [تحسين] المسارات المتوازية (Parallel Routes): توفير مسارات catch-all غير المتطابقة مع جميع المعلمات المعروفة (PR)
  • [تحسين] تكوين bundlePagesExternals أصبح الآن مستقرًا وتمت إعادة تسميته إلى bundlePagesRouterDependencies
  • [تحسين] تكوين serverComponentsExternalPackages أصبح الآن مستقرًا وتمت إعادة تسميته إلى serverExternalPackages
  • [تحسين] create-next-app: المشاريع الجديدة تتجاهل جميع ملفات .env افتراضيًا (PR)
  • [وثائق] تحسين وثائق المصادقة (PR)
  • [وثائق] حزمة @next/env (PR)

لمعرفة المزيد، تحقق من دليل الترقية.

المساهمون

Next.js هو نتيجة العمل المشترك لأكثر من 3000 مطور فردي، وشركاء صناعيين مثل Google وMeta، وفريقنا الأساسي في Vercel. هذا الإصدار تم تقديمه بواسطة:

شكرًا جزيلاً لـ @devjiwonchoi, @ijjk, @Ethan-Arrowood, @sokra, @kenji-webdev, @wbinnssmith, @huozhi, @domdomegg, @samcx, @Jaaneek, @evanwinter, @wyattjoh, @kdy1, @balazsorban44, @feedthejim, @ztanner, @ForsakenHarmony, @kwonoj, @delbaoliveira, @stipsan, @leerob, @shuding, @xiaohanyu, @timneutkens, @dvoytenko, @bobaaaaa, @bgw, @gaspar09, @souporserious, @unflxw, @kiner-tang, @Ehren12, @EffectDoplera, @IAmKushagraSharma, @Auxdible, @sean-rallycry, @Jeffrey-Zutt, @eps1lon, @jeanmax1me, @unstubbable, @NilsJacobsen, @PaulAsjes, @adiguno, @ryan-nauman, @zsh77, @KagamiChan, @steveluscher, @MehfoozurRehman, @vkryachko, @chentsulin, @samijaber, @begalinsaf, @FluxCapacitor2, @lukahartwig, @brianshano, @pavelglac, @styfle, @symant233, @HristovCodes, @karlhorky, @jonluca, @jonathan-ingram, @mknichel, @sopranopillow, @Gomah, @imddc, @notrab, @gabrielrolfsen, @remorses, @AbhiShake1, @agadzik, @ryota-murakami, @rishabhpoddar, @rezamauliadi, @IncognitoTGT, @webtinax, @BunsDev, @nisabmohd, @z0n, @bennettdams, @joeshub, @n1ckoates, @srkirkland, @RiskyMH, @coopbri, @okoyecharles, @diogocapela, @dnhn, @typeofweb, @davidsa03, @imranolas, @lubieowoce, @maxhaomh, @mirasayon, @blvdmitry, @hwangstar156, @lforst, @emmerich, @christian-bromann, @Lsnsh, @datner, @hiro0218, @flybayer, @ianmacartney, @ypessoa, @ryohidaka, @icyJoseph, @Arinji2, @lovell, @nsams, @Nayeem-XTREME, @JamBalaya56562, @Arindam200, @gaojude, @qqww08, @todor0v, @coltonehrman, و @wiesson للمساعدة!