output

أثناء عملية البناء، سيتتبع Next.js تلقائيًا كل صفحة والتبعيات الخاصة بها لتحديد جميع الملفات المطلوبة لنشر نسخة إنتاجية من تطبيقك.

تساعد هذه الميزة في تقليل حجم عمليات النشر بشكل كبير. في السابق، عند النشر باستخدام Docker، كنت بحاجة إلى تثبيت جميع الملفات من dependencies الحزمة لتشغيل next start. بدءًا من Next.js 12، يمكنك الاستفادة من تتبع ملفات الإخراج في دليل .next/ لتضمين الملفات الضرورية فقط.

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

كيفية العمل

أثناء next build، سيستخدم Next.js @vercel/nft لتحليل import و require واستخدام fs بشكل ثابت لتحديد جميع الملفات التي قد تحتاجها الصفحة.

يتم أيضًا تتبع خادم الإنتاج الخاص بـ Next.js للملفات المطلوبة وإخراجها في .next/next-server.js.nft.json والتي يمكن الاستفادة منها في الإنتاج.

للاستفادة من ملفات .nft.json المنبعثة إلى دليل الإخراج .next، يمكنك قراءة قائمة الملفات في كل تتبع والتي تكون مرتبطة بملف .nft.json ثم نسخها إلى موقع النشر الخاص بك.

النسخ التلقائي للملفات المتتبعة

يمكن لـ Next.js إنشاء مجلد standalone تلقائيًا والذي ينسخ فقط الملفات الضرورية لنشر الإنتاج بما في ذلك ملفات مختارة من node_modules.

للاستفادة من هذا النسخ التلقائي، يمكنك تمكينه في ملف next.config.js:

next.config.js
module.exports = {
  output: 'standalone',
}

سيؤدي هذا إلى إنشاء مجلد في .next/standalone والذي يمكن نشره بمفرده دون تثبيت node_modules.

بالإضافة إلى ذلك، يتم إخراج ملف server.js بسيط أيضًا والذي يمكن استخدامه بدلاً من next start. لا يقوم هذا الخادم البسيط بنسخ مجلدات public أو .next/static افتراضيًا حيث يُفضل التعامل مع هذه المجلدات عبر CDN، على الرغم من أنه يمكن نسخ هذه المجلدات يدويًا إلى standalone/public و standalone/.next/static، وبعد ذلك سيقدم ملف server.js هذه الملفات تلقائيًا.

معلومة مفيدة:

  • إذا كان مشروعك بحاجة إلى الاستماع إلى منفذ أو اسم مضيف محدد، يمكنك تعريف متغيرات البيئة PORT أو HOSTNAME قبل تشغيل server.js. على سبيل المثال، قم بتشغيل PORT=8080 HOSTNAME=0.0.0.0 node server.js لبدء الخادم على http://0.0.0.0:8080.
  • إذا كان مشروعك يستخدم تحسين الصور مع محمل loader الافتراضي، يجب تثبيت sharp كتبعية:
Terminal
npm i sharp
Terminal
yarn add sharp
Terminal
pnpm add sharp
Terminal
bun add sharp

محاذير

  • أثناء التتبع في إعدادات monorepo، يتم استخدام دليل المشروع افتراضيًا للتتبع. بالنسبة لـ next build packages/web-app، سيكون packages/web-app هو جذر التتبع ولن يتم تضمين أي ملفات خارج هذا المجلد. لتضمين ملفات خارج هذا المجلد، يمكنك تعيين experimental.outputFileTracingRoot في ملف next.config.js.
packages/web-app/next.config.js
module.exports = {
  experimental: {
    // هذا يتضمن ملفات من قاعدة monorepo بمستويين للأعلى
    outputFileTracingRoot: path.join(__dirname, '../../'),
  },
}
  • هناك بعض الحالات التي قد يفشل فيها Next.js في تضمين الملفات المطلوبة، أو قد يتضمن ملفات غير مستخدمة عن طريق الخطأ. في هذه الحالات، يمكنك الاستفادة من experimental.outputFileTracingExcludes و experimental.outputFileTracingIncludes على التوالي في next.config.js. يقبل كل تكوين كائنًا مع minimatch globs للمفتاح لمطابقة صفحات محددة ومصفوفة من globs مرتبطة بجذر المشروع لتضمينها أو استبعادها في التتبع.
next.config.js
module.exports = {
  experimental: {
    outputFileTracingExcludes: {
      '/api/hello': ['./un-necessary-folder/**/*'],
    },
    outputFileTracingIncludes: {
      '/api/another': ['./necessary-folder/**/*'],
    },
  },
}
  • حاليًا، لا يفعل Next.js أي شيء مع ملفات .nft.json المنبعثة. يجب قراءة الملفات بواسطة منصة النشر الخاصة بك، مثل Vercel، لإنشاء نشر بسيط. في إصدار مستقبلي، من المخطط إصدار أمر جديد للاستفادة من ملفات .nft.json هذه.

turbotrace التجريبي

يمكن أن يكون تتبع التبعيات بطيئًا لأنه يتطلب حسابات وتحليلات معقدة للغاية. لقد أنشأنا turbotrace بلغة Rust كبديل أسرع وأذكى للتنفيذ بلغة JavaScript.

لتمكينه، يمكنك إضافة التكوين التالي إلى ملف next.config.js:

next.config.js
module.exports = {
  experimental: {
    turbotrace: {
      // التحكم في مستوى تسجيل turbotrace، الافتراضي هو `error`
      logLevel?:
      | 'bug'
      | 'fatal'
      | 'error'
      | 'warning'
      | 'hint'
      | 'note'
      | 'suggestions'
      | 'info',
      // التحكم فيما إذا كان سجل turbotrace يجب أن يتضمن تفاصيل التحليل، الافتراضي هو `false`
      logDetail?: boolean
      // عرض جميع رسائل السجل دون حدود
      // يعرض turbotrace رسالة سجل واحدة فقط لكل فئة افتراضيًا
      logAll?: boolean
      // التحكم في دليل السياق لـ turbotrace
      // لن يتم تتبع الملفات خارج دليل السياق
      // تعيين `experimental.outputFileTracingRoot` له نفس التأثير
      // إذا تم تعيين كل من `experimental.outputFileTracingRoot` وهذا الخيار، سيتم استخدام `experimental.turbotrace.contextDirectory`
      contextDirectory?: string
      // إذا كان هناك تعبير `process.cwd()` في الكود الخاص بك، يمكنك تعيين هذا الخيار لإخبار `turbotrace` بقيمة `process.cwd()` أثناء التتبع.
      // على سبيل المثال، سيتم تتبع require(process.cwd() + '/package.json') كـ require('/path/to/cwd/package.json')
      processCwd?: string
      // التحكم في الحد الأقصى لاستخدام الذاكرة لـ `turbotrace`، بوحدة `MB`، الافتراضي هو `6000`.
      memoryLimit?: number
    },
  },
}