خادم مخصص

أمثلة

بشكل افتراضي، يتضمن Next.js خادمه الخاص مع next start. إذا كان لديك خادم خلفي موجود، فلا يزال بإمكانك استخدامه مع Next.js (هذا ليس خادمًا مخصصًا). يسمح لك خادم Next.js المخصص ببدء خادم برمجيًا بنسبة 100% لاستخدام أنماط الخوادم المخصصة. معظم الوقت، لن تحتاج إلى هذا - ولكنه متاح للتخصيص الكامل.

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

  • قبل اتخاذ قرار باستخدام خادم مخصص، يرجى ملاحظة أنه يجب استخدامه فقط عندما لا يستطيع جهاز التوجيه المدمج في Next.js تلبية متطلبات تطبيقك. سيؤدي الخادم المخصص إلى إزالة تحسينات الأداء المهمة، مثل وظائف الخادم (serverless functions) و**التحسين الثابت التلقائي (Automatic Static Optimization).**
  • لا يمكن نشر خادم مخصص على Vercel.
  • وضع الإخراج المستقل، لا يتتبع ملفات الخادم المخصص ويخرج هذا الوضع ملف server.js منفصلًا وحديثًا بدلاً من ذلك.

إليك مثالًا على خادم مخصص:

server.js
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')

const dev = process.env.NODE_ENV !== 'production'
const hostname = 'localhost'
const port = 3000
// عند استخدام middleware يجب توفير `hostname` و `port` أدناه
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  createServer(async (req, res) => {
    try {
      // تأكد من تمرير `true` كوسيطة ثانية لـ `url.parse`.
      // هذا يخبرها بتحليل جزء الاستعلام من URL.
      const parsedUrl = parse(req.url, true)
      const { pathname, query } = parsedUrl

      if (pathname === '/a') {
        await app.render(req, res, '/a', query)
      } else if (pathname === '/b') {
        await app.render(req, res, '/b', query)
      } else {
        await handle(req, res, parsedUrl)
      }
    } catch (err) {
      console.error('حدث خطأ أثناء التعامل مع', req.url, err)
      res.statusCode = 500
      res.end('خطأ داخلي في الخادم')
    }
  })
    .once('error', (err) => {
      console.error(err)
      process.exit(1)
    })
    .listen(port, () => {
      console.log(`> جاهز على http://${hostname}:${port}`)
    })
})

ملف server.js لا يمر عبر babel أو webpack. تأكد من أن بناء الجملة والمصادر التي يتطلبها هذا الملف متوافقة مع إصدار node الحالي الذي تقوم بتشغيله.

لتشغيل الخادم المخصص، ستحتاج إلى تحديث scripts في package.json كما يلي:

package.json
{
  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
  }
}

يستخدم الخادم المخصص الاستيراد التالي لربط الخادم بتطبيق Next.js:

const next = require('next')
const app = next({})

استيراد next أعلاه هو دالة تستقبل كائنًا مع الخيارات التالية:

الخيارالنوعالوصف
confObjectنفس الكائن الذي ستستخدمه في next.config.js. الافتراضي هو {}
customServerBoolean(اختياري) اضبط على false عندما يكون الخادم قد تم إنشاؤه بواسطة Next.js
devBoolean(اختياري) ما إذا كان سيتم تشغيل Next.js في وضع التطوير أم لا. الافتراضي هو false
dirString(اختياري) موقع مشروع Next.js. الافتراضي هو '.'
quietBoolean(اختياري) إخفاء رسائل الخطأ التي تحتوي على معلومات الخادم. الافتراضي هو false
hostnameString(اختياري) اسم المضيف الذي يعمل عليه الخادم
portNumber(اختياري) المنفذ الذي يعمل عليه الخادم
httpServernode:http#Server(اختياري) خادم HTTP الذي يعمل عليه Next.js

يمكن بعد ذلك استخدام app المُعاد للسماح لـ Next.js بمعالجة الطلبات حسب الحاجة.

تعطيل توجيه نظام الملفات

بشكل افتراضي، سيقدم Next كل ملف في مجلد pages تحت مسار مطابق لاسم الملف. إذا كان مشروعك يستخدم خادمًا مخصصًا، فقد يؤدي هذا السلوك إلى تقديم نفس المحتوى من مسارات متعددة، مما قد يسبب مشاكل في تحسين محركات البحث (SEO) وتجربة المستخدم (UX).

لتعطيل هذا السلوك ومنع التوجيه بناءً على الملفات في pages، افتح next.config.js وعطل إعداد useFileSystemPublicRoutes:

next.config.js
module.exports = {
  useFileSystemPublicRoutes: false,
}

ملاحظة: useFileSystemPublicRoutes يعطل مسارات أسماء الملفات من العرض من جانب الخادم (SSR)؛ قد يظل التوجيه من جانب العميل قادرًا على الوصول إلى تلك المسارات. عند استخدام هذا الخيار، يجب أن تحمي ضد التنقل إلى المسارات التي لا تريدها برمجيًا.

قد ترغب أيضًا في تكوين جهاز التوجيه من جانب العميل لمنع إعادة التوجيه من جانب العميل إلى مسارات أسماء الملفات؛ لذلك راجع router.beforePopState.