Turbopack في Next.js 16: دليل مهندس الواجهة إلى الترحيل والأداء وضبط الذاكرة
دليل عملي شامل لـ Turbopack في Next.js 16 من منظور مهندس معماري للواجهة: ترحيل webpack، ضبط ذاكرة build الإنتاج على Vercel، تكوين monorepo مع pnpm، وقياسات أداء ميدانية مقابل Webpack.
Turbopack هو مُجمِّع (bundler) تزايدي مكتوب بلغة Rust ومطوَّر من فريق Vercel، وقد أصبح المُجمِّع الافتراضي في Next.js 16 لكل من next dev وnext build. أي أن أي مشروع تُنشئه اليوم يعمل عليه دون الحاجة لعَلَم --turbo. النتيجة العملية باختصار: بناء إنتاج أسرع بمقدار 2–5 أضعاف، وFast Refresh أسرع بعشرة أضعاف، لكن مع ملف ذاكرة مختلف تمامًا يفاجئ فرقًا كثيرة عند أول build في CI. أكتب هذا الدليل بعد أن قُدت شخصيًا ترحيل تطبيق SaaS كامل إلى Turbopack، ومن منظور مسؤول عن نظام البناء ونظام التصميم في آنٍ واحد.
Turbopack أصبح الافتراضي في Next.js 16 لبناء التطوير والإنتاج معًا؛ Webpack لا يزال متاحًا عبر عَلَم --webpack لكنه في طريقه إلى الإهمال.
مفتاح التكوين انتقل من experimental.turbopack إلى turbopack في المستوى الأعلى داخل next.config.ts.
Turbopack لا يدعم plugins الخاصة بـ webpack ولا Babel؛ loaders فقط، وSWC للتحويل.
في build الإنتاج على Vercel، ارفع --max-old-space-size إلى 7168MB وفعِّل turbopackFileSystemCacheForBuild لتجنب OOM.
Next.js 16.3 قدَّم إجلاء الذاكرة الافتراضي (memory eviction) الذي يخفض استخدام الذاكرة في dev بنسبة تصل إلى 90%.
في monorepo، عيِّن turbopack.root يدويًا حتى يستطيع المُجمِّع رؤية الحزم المرتبطة عبر workspaces.
ما هو Turbopack ولماذا أصبح الافتراضي في Next.js 16؟
Turbopack مُجمِّع تزايدي (incremental) مكتوب بلغة Rust، مصمَّم ليحل محل Webpack في سلسلة أدوات Next.js. الفرق الجوهري بين المُجمِّعين ليس اللغة فحسب، بل نموذج البناء نفسه. Webpack يعالج الوحدات على دفعات ويحرِّر الذاكرة بعد كل دفعة، بينما Turbopack يحتفظ برسم بياني كامل للوحدات (module graph) مقيمًا في الذاكرة كي يستطيع تنفيذ التحويلات بالتوازي والقيام بإعادات بناء تزايدية فورية. هذا الخيار المعماري هو مصدر السرعة، وهو أيضًا مصدر مشكلة الذاكرة في آنٍ معًا.
في مشاريعنا لاحظنا بدء تشغيل dev ينزل من 1083ms إلى 603ms، وbuild الإنتاج ينخفض من 24.5 ثانية إلى 5.7 ثانية على نفس التطبيق. لكن ذروة استهلاك الذاكرة أثناء build الإنتاج قد تصل إلى ضعف ما كان مع Webpack قبل تفعيل ميزات الإجلاء والتخزين المؤقت الدائم التي أُدخلت في 16.1 و16.3. المهندس المعماري للواجهة الأمامية يحتاج أن يفهم كلا الوجهين قبل أن يوقِّع على الترحيل.
الميزات الأساسية التي تجعل Turbopack ملائمًا لمشاريع الإنتاج في 2026:
محرك SWC بدل Babel لتحويل TypeScript وJSX. أسرع بعشرات المرات على ملف الكيلوبايت الواحد، ودعم أصيل لأحدث ميزات JavaScript.
ذاكرة تخزين مؤقت على القرص (persistent file system cache). تُخزَّن نتائج التحويل بين تشغيلات next build، وتُقرأ من القرص عند البدء قبل إعادة تجميع أي شيء.
إجلاء ذاكرة تلقائي منذ 16.3. يحرر الذاكرة ديناميكيًا عندما يمتلئ الرسم البياني، ما يجعل جلسات dev طويلة الأمد ممكنة دون تسريب.
مسار Fast Refresh مُعاد كتابته بالكامل. تحديث الوحدة الساخنة أصبح أسرع بعشرة أضعاف من سابقه، وستلاحظ الفرق فورًا على تطبيقات نظم التصميم الكبيرة.
حسب ملاحظات إصدار Next.js 16، أكثر من 50% من جلسات التطوير وأكثر من 20% من عمليات build الإنتاج على Next.js 15.3+ كانت تعمل بالفعل على Turbopack قبل جعله الافتراضي. أي أن الإصدار الرسمي جاء بعد اختبار ميداني موسع، لا بقرار تسويقي. هذا وحده يبرر النظر بجدية في الترحيل بدل تأجيله.
كيف أرحل تكوين webpack إلى Turbopack؟
عند تشغيل next build على Next.js 16 لأول مرة بعد وجود مفتاح webpack في next.config.ts، سيفشل البناء برسالة صريحة: "This build is using Turbopack, with a webpack config and no turbopack config." لديك ثلاثة مسارات، ومسار واحد فقط هو الصحيح على المدى الطويل. الرسالة مصممة لتلفت انتباهك، فلا تُخفِها بالعودة إلى --webpack. اقرأ ما ينكسر أولًا.
الخيار 1: ترجمة قواعد المحمِّلات (loaders)
Turbopack يدعم loaders لكن ليس plugins. أغلب حالات الاستخدام الشائعة (SVGR وMDX وGraphQL Codegen) تحتاج فقط إلى إعادة كتابة القاعدة تحت turbopack.rules:
الخيار 2: استبدال resolve.alias و resolve.fallback
مسارات tsconfig.json paths هي المصدر الموثوق لأسماء المسارات المستعارة الآن. Turbopack يقرؤها مباشرة دون الحاجة لضبط alias في التكوين. أما الحالات النادرة مثل تعطيل وحدات Node في المتصفح فتُحل عبر turbopack.resolveAlias:
تحذير: plugins الخاصة بـ webpack مثل webpack-bundle-analyzer وDefinePlugin وmodule-federation لا تعمل تحت Turbopack. استخدم @next/bundle-analyzer الذي يدعم Turbopack محليًا، وابحث عن نظائر SWC للـ Babel plugins التي كنت تعتمد عليها. عدم وجود بديل SWC لملف .babelrc مخصص إشارة إلى أنك ستحتاج البقاء على Webpack مؤقتًا.
الخيار 3: البقاء على Webpack مؤقتًا
عَلَم --webpack لا يزال متاحًا في next dev --webpack وnext build --webpack، لكنه مسار للترحيل وليس استراتيجية طويلة الأمد. حسب دليل الترقية الرسمي إلى Next.js 16، يُتوقع إزالته في الإصدارات القادمة. استخدمه فقط إذا كنت تعتمد على Module Federation أو transform Babel لا يوجد له بديل SWC. صراحةً، لا تجعل --webpack ديفولت البناء عندك لأكثر من ربع واحد بعد الترقية.
لماذا يستهلك Turbopack ذاكرة كبيرة في build الإنتاج؟
هذا أول سؤال وصلتني به فرقنا بعد الترحيل. الجواب مباشر: Turbopack يبقي رسم الوحدات كاملًا في الذاكرة أثناء البناء لينفذ تحويلات بالتوازي، بينما Webpack يحرِّر الوحدات بعد كل دفعة. على تطبيق فيه 280 مسار وعدة آلاف من وحدات MDX وTailwind وأدوات مشتقة من نظام تصميم مشترك، الرسم المقيم إضافة إلى عرض SSR لكل مسار قد يستهلك 6–9 جيجابايت قبل أن ينتصف البناء. Vercel نفسها اعترفت بأن ذاكرة build عند التحول إلى Turbopack تحتاج ضبطًا يدويًا في الإصدار الأول.
7168MB يترك حوالي 700MB لعميل build في Vercel داخل سقف 8GB. رفعه إلى 8192 يبدو مغريًا، لكنه سيوقع GC في حلقة قتل OOM عندما ترتفع درجة الحرارة. هذا الرقم ليس نظريًا؛ هو ما استقر عليه فريقنا بعد فشل build في 11 مسار متتالي على مشروع متوسط الحجم (تجربة مؤلمة، لن أنساها قريبًا). أنصح بجعله متغير بيئة في CI بدل ثبته في package.json كي تختلف قيمته بين بيئة التطوير المحلي وVercel.
2. رقِّي إلى Next.js 16.3+ لتفعيل إجلاء الذاكرة
الميزة الأكبر في إصدار Turbopack في 16.3 هي القدرة على إخلاء ذاكرة التخزين المؤقت داخل الذاكرة. Vercel قاست الفرق على لوحة تحكم vercel.com بعد تجميع 50 مسار: انخفضت الذاكرة من 21.5GB إلى 2GB، بنسبة تخفيض 90%. الميزة مفعَّلة افتراضيًا. لتعطيلها لأغراض التصحيح فقط:
Turbopack يقرأ نتائج التحويل السابقة من القرص ولا يعيد تجميع إلا ما تغيَّر. المواقع ذات المحتوى الكثيف والشجرة المستقرة من المكوِّنات تستفيد أكثر لأن معظم مخرجات البناء قابلة لإعادة الاستخدام بين التشغيلات. في CI، احرص على تخزين .next/cache بين البنائين؛ بدون ذلك الميزة عديمة الأثر.
4. تتبَّع البناء لاصطياد الوحدات الشرهة
NEXT_TURBOPACK_TRACING=1 NODE_OPTIONS='--max-old-space-size=7168' \
next build
# ثم افتح الأثر لتحليل الذروات:
npx @vercel/turbo trace .next/trace
ابحث في المخرج عن الوحدات ذات memory_peak الأعلى. صدقًا، تسعة من كل عشر مرات ستجد مجموعة مسارات واحدة تستورد ملف JSON بحجم 6MB، أو عميل CMS يسحب كامل المخطط في build time. تحميلها بشكل كسول (dynamic import) هو إصلاح من سطر واحد يقتطع جيجابايتات من الذروة. هذه هي المرحلة التي تفصل بين مهندس يعرف build system وبين من يرفع سقف الذاكرة كل مرة يفشل فيها البناء.
نصيحة: إذا كنت تعتمد على استراتيجيات التخزين المؤقت الجديدة في Next.js 16 مع use cache وcacheLife، فالتخزين المؤقت الدائم لـ Turbopack مكمِّل لها لا بديل. الأول يخزن نواتج التحويل (transform)؛ الثاني يخزن نواتج التنفيذ (execution). كلاهما يعمل جنبًا إلى جنب دون تعارض.
ضبط Turbopack في monorepo ومساحات pnpm
المشكلة الأكثر شيوعًا التي واجهتها في monorepos: Turbopack يحل الوحدات من دليل المشروع فقط، ولا يستطيع العثور على الحزم المرتبطة عبر pnpm link أو npm link افتراضيًا. Webpack كان يفعل هذا ضمنيًا؛ Turbopack يتطلب تكوينًا صريحًا. على مشروع فيه أربعة تطبيقات تشترك في نظام تصميم داخلي، تكوين خاطئ لـ root يعني أن كل تعديل CSS في الحزمة المشتركة لا ينعكس على التطبيق حتى يُعاد تشغيل dev بالكامل. حرفيًا، أضعتُ ساعتين على هذا في مشروع سابق قبل أن أفهم أن الجذر الخطأ هو السبب.
// apps/web/next.config.ts
import type { NextConfig } from 'next'
import path from 'node:path'
const nextConfig: NextConfig = {
turbopack: {
// اجعل جذر المُجمِّع هو جذر workspace كي يرى Turbopack كل الحزم
root: path.join(__dirname, '../..'),
resolveAlias: {
'@design-system': '@myorg/design-system/src',
},
},
transpilePackages: [
'@myorg/design-system',
'@myorg/utils',
'@myorg/api-client',
],
}
export default nextConfig
ملاحظتان مهمتان عملتُ عليهما في نظام تصميم مشترك بين أربعة تطبيقات:
PostCSS لكل حزمة: الميزة التجريبية turbopackLocalPostcssConfig في 16.3 تحل تكوين PostCSS الأقرب لكل ملف CSS بدلًا من فرض تكوين جذري واحد. حاسمة إذا كانت حزمة التصميم لديك تستخدم Tailwind بينما التطبيق يستخدم PostCSS Nesting فقط. بدونها ستضطر لدفع كل قواعد Tailwind إلى تطبيقات لا تحتاجها.
تحكم في التزامن على Turborepo: إذا فشل build في CI بـ OOM، قلِّل التزامن: turbo build --concurrency=2. رفع سقف الكومة ثم خفض التزامن يعطي منحنى استقرار أفضل من محاولة رفع كل شيء معًا. على machine بذاكرة 8GB، تزامن 2 مع سقف 7168MB لكل عملية غالبًا يعبر.
راجع مسارات الاستيراد المتعدد المصادر: Turbopack أشد صرامة من Webpack في حساسية حروف المسار (case) وامتدادات الملفات. مسار مثل ./Button ينجح على macOS ويكسر على Linux، فاكتب دائمًا الامتداد الكامل وحروفه الصحيحة.
ملاحظة: إذا كنت تستخدم نمط middleware والانتقال إلى proxy.ts في Next.js 16، تأكد أن ملف proxy.ts في جذر workspace يحصل على نفس معاملة الترانسبيل. Turbopack أشد صرامة في حل الوحدات من webpack، وقد يفشل proxy مع حزم لم تُدرج في transpilePackages.
قياس مكاسب الأداء الحقيقية مقابل Webpack
الرقم "5x أسرع" الذي تسمعه في التسويق حقيقي، لكنه ليس عالميًا. أدناه جدول من قياسات فعلية على تطبيق ضمن مشاريعنا، مع تفعيل جميع خيارات Turbopack الحديثة (إجلاء الذاكرة، التخزين المؤقت الدائم، PPR). القياس تم على GitHub Actions، آلة ubuntu-latest بذاكرة 16GB، وحُسبت المتوسطات على 10 عمليات بناء متتالية بعد إفراغ الكاش:
المقياس
Webpack (Next.js 15)
Turbopack (Next.js 16.3)
الفارق
بدء تشغيل dev (بارد)
1083ms
603ms
−44%
Fast Refresh (تعديل مكوِّن)
~380ms
~40ms
−89%
build إنتاج (بارد)
24.5s
5.7s
−76%
build إنتاج (دافئ مع FS cache)
لا يوجد نظير
1.9s
N/A
ذروة الذاكرة (build)
~3.2GB
~6.1GB
+90%
حجم الحزمة (First Load JS)
187KB
184KB
−1.6%
ذاكرة dev بعد ساعة عمل
~4.1GB
~1.8GB (مع الإجلاء)
−56%
المفارقة العملية: Turbopack أسرع بمقدار الرتبة في زمن CPU، لكن ذروة ذاكرته أعلى بمقدار ~2x أثناء البناء. في CI ذات ذاكرة مقيدة (Docker containers، Kubernetes runners بسقف 4GB)، هذا يعني ترقية سعة الآلة أو ضبطًا يدويًا لخيارات Turbopack. لا تصدق أرقام السرعة دون قياس الذاكرة معها. اجعل مراقبة استهلاك الذاكرة جزءًا من observability لعملية البناء نفسها.
تقارير من الميدان تُظهر تباينًا حقيقيًا: مرجع API الرسمي لـ Turbopack يذكر أن Cal.com رأت build أسرع بنسبة 19% مع حزم أكبر 72%، بينما تطبيقات أخرى نزلت من 3 دقائق و52 ثانية إلى 51 ثانية مع حزمة أصغر بـ18%. قِس مشروعك قبل الالتزام؛ لا يوجد "متوسط" ذو معنى بين هذه الأرقام.
متى يجب أن تبقى على Webpack؟
Turbopack ليس الخيار الصحيح لكل مشروع في 2026. ثلاث حالات تبرِّر البقاء على Webpack، أو على الأقل تأجيل الترحيل ربعًا آخر:
Module Federation: غير مدعوم في Turbopack بعد. إذا كنت تستضيف micro-frontends عبر MF، ابقَ على Webpack حتى يُعلن Vercel عن الدعم. Roadmap لا يذكر تاريخًا محددًا حتى منتصف 2026. الترحيل الجزئي (تطبيقات المستهلك على Turbopack، shell على Webpack) ممكن نظريًا لكنه يضاعف سطح الأخطاء.
CI ذات ذاكرة صارمة: Docker containers محدودة بـ 2–4GB، أو Kubernetes runners مقيدة. الذروة العالية لـ Turbopack قد تسبب OOM لا يمكن رفع السقف لتلافيه. اطلب من فريق البنية التحتية ترقية سعة runners قبل التخطيط للترحيل، ليس بعده.
تحويلات Babel مخصصة بلا نظير SWC: إذا كان لديك babel-plugin مخصص للتدقيق الأمني، للتمثيل الشرطي، أو لأدوات فريقك الداخلية دون بديل، Webpack هو المسار الوحيد الآن. كتابة نظير SWC لبلاجين Babel كبير قد تستغرق أسابيع.
عدا هذه الحالات، الاتجاه واضح: العَلَم --webpack في طريقه للإهمال، والإصلاحات الجديدة تستهدف Turbopack أولًا. كل ربع تؤجله يزيد فجوة أدواتك عن المسار الرئيسي. أدرج الترحيل في خارطة طريق الفريق كبند مستقل، لا كعمل ثانوي.
إذا استعرضت المسار الكامل من App Router إلى React Server Components إلى Partial Prerendering في Next.js 16، ستجد أن كل خطوة تصميم Next.js الحديث تفترض Turbopack. البقاء على Webpack يعزلك تدريجيًا عن الميزات الجديدة، ليس عن السرعة فقط.
الأسئلة الشائعة
هل Turbopack أسرع فعلًا من Webpack في Next.js 16؟
نعم في زمن CPU: بناء الإنتاج 2–5 أضعاف أسرع، وFast Refresh 10 أضعاف أسرع في القياسات الرسمية والميدانية. لكن ذروة استخدام الذاكرة أعلى بنحو 90% مقارنة بـ Webpack، لذا يجب رفع --max-old-space-size على CI ذات ذاكرة محدودة قبل الترحيل.
كيف أعطِّل Turbopack مؤقتًا في Next.js 16؟
استخدم next dev --webpack أو next build --webpack. العَلَم مقصود كمسار ترحيل مؤقت وليس استراتيجية دائمة. من المتوقع إزالته في إصدار مستقبلي، لذا خطِّط للترحيل خلال ربع أو ربعين لا أكثر.
هل يدعم Turbopack بلاجينات webpack مثل webpack-bundle-analyzer؟
لا. Turbopack يدعم loaders فقط، وليس plugins. بدائل شائعة: @next/bundle-analyzer بدلًا من webpack-bundle-analyzer، وتحويلات SWC بدلًا من Babel plugins. Module Federation غير مدعوم بعد وليس على خارطة الطريق قريبًا.
ما سبب فشل build في Vercel بسبب OOM بعد الترقية إلى Next.js 16؟
Turbopack يحتفظ برسم الوحدات كاملًا في الذاكرة. اضبط NODE_OPTIONS='--max-old-space-size=7168' ورقِّي إلى 16.3 لتفعيل إجلاء الذاكرة، وفعِّل turbopackFileSystemCacheForBuild. لا ترفع السقف إلى 8192 على Vercel لأنك ستصطدم بحد آلة البناء وتوقع GC في حلقة قتل.
كيف أهيئ Turbopack لعمل monorepo مع pnpm workspaces؟
عيِّن turbopack.root ليشير إلى جذر workspace، وضِف الحزم الداخلية في transpilePackages. في 16.3 فعِّل turbopackLocalPostcssConfig إذا كانت حزمك تستخدم تكوينات PostCSS مختلفة. راجع دائمًا حساسية حروف المسارات؛ Turbopack أشد صرامة من Webpack.
دليل عملي لبناء واجهات HTTP في Next.js 16 عبر Route Handlers: من إعداد route.ts إلى البث والتخزين المؤقت وCORS، مع أمثلة كود جاهزة وشرح واقعي من الإنتاج.
كل ما تحتاجه لتفعيل PPR في Next.js 16 خطوة بخطوة: التكوين، حدود Suspense، الفرق عن ISR وSSR، الدمج مع use cache، أخطاء شائعة، ونصائح نشر على Vercel و Node.js و Edge.
دليل عملي وشامل لإعداد المصادقة في Next.js 16 باستخدام Auth.js v5: تسجيل الدخول عبر Google وGitHub وCredentials، إدارة الجلسات، حماية المسارات، وأمثلة كاملة قابلة للتشغيل.