Inertia.js 3.8: المكوّن WhenMounted ودعم BigInt بالتفصيل

إذا كنت تبني تطبيقًا بـ Inertia مع SSR (العرض من جهة الخادم)، فلا بد أنك رأيت الخطأ المزعج window is not defined عند وضع مكوّن يعتمد على المتصفح في صفحتك. وإذا كان عندك معرفات رقمية ضخمة (مثل Snowflake IDs) فربما لاحظت أن أرقامك «تتغير» وحدها عند وصولها إلى الواجهة. الإصدار 3.8.0 من Inertia.js، الذي صدر في 2 أكتوبر 2026 بحسب Laravel News، يعالج المشكلتين بميزتين جديدتين، مع إصلاحات تستحق الانتباه.

المكوّن WhenMounted: كود المتصفح فقط، بدون أخطاء SSR

المشكلة

عند SSR تُنفَّذ مكوّناتك على الخادم حيث لا يوجد window ولا document. فإذا كان مكوّن مثل رسم بياني يقرأ window.innerWidth أثناء العرض، ينهار العرض على الخادم.

الحل

المكوّن WhenMounted يعرض محتوى بديلًا (fallback) على الخادم، ثم يعرض المحتوى الفعلي بعد أن يُركَّب (mounted) في المتصفح. المقال يذكر أن البديل يظهر فقط أثناء SSR ومع أول عرض للـ hydration، فيطابق أول عرض في المتصفح HTML القادم من الخادم تمامًا، ولا يحدث hydration mismatch.

مثال Vue كما في المقال:

<template>
    <WhenMounted>
        <SalesChart />
        <template #fallback>
            <p>Loading chart...</p>
        </template>
    </WhenMounted>
</template>

وفي React يجب أن يكون الـ children دالة، حتى لا تُقيَّم على الخادم:

<WhenMounted fallback={<p>Loading chart...</p>}>
  {() => <SalesChart width={window.innerWidth} />}
</WhenMounted>

لاحظ الفرق: في Vue تضع المحتوى مباشرة مع قالب #fallback، أما في React فتمرر fallback كخاصية وتلف المحتوى بدالة. السبب في الدالة أنها لا تُستدعى إلا في المتصفح، فلا يُنفَّذ window.innerWidth على الخادم. المساهم في هذه الميزة هو Evan Burrell.

دعم BigInt: أرقامك الكبيرة لن تتغير بعد اليوم

لماذا تتغير الأرقام؟

PHP تتعامل مع أعداد صحيحة بدقة 64 بت، لكن عند تحويلها إلى JSON ثم قراءتها في JavaScript تُحوَّل إلى Number، وهو رقم بفاصلة عائمة مزدوج الدقة (IEEE-754) يحتفظ بالدقة الكاملة حتى 2^53 − 1 فقط (وهي القيمة Number.MAX_SAFE_INTEGER، أي 9007199254740991). ما فوق ذلك يُقرَّب. المقال يعطي مثالًا واضحًا: الرقم 900719925474099988 يصبح 900719925474100000. وإذا كان هذا معرف سجل أو طلب، فقد أصبحت تشير إلى سجل آخر أو لا شيء.

كيف تفعّل الميزة؟

الميزة اختيارية، وتفعّلها بإحدى الطرق:

  • عالميًا: بضبط الخيار preserve_big_integers في الملف config/inertia.php، أو بمتغير البيئة INERTIA_PRESERVE_BIG_INTEGERS.
  • لاستجابة واحدة: باستدعاء الدالة ->preserveBigIntegers().

ماذا يحدث خلف الكواليس؟

الأعداد الكبيرة تُرمَّز كعلامات من الشكل { "$bigint": "..." }، ثم تتحول في الواجهة إلى قيم BigInt الأصلية في JavaScript، فتحافظ على دقتها. فيمكنك في Vue كتابة:

<template>
    <p>Order {{ id }}</p>
    <!-- Order 900719925474099988 -->
</template>

وعند إرسال هذه القيم من نموذج (Form) أو عبر Precognition، تتحول إلى نصوص من الأرقام فقط، وتقبلها قاعدة التحقق integer في Laravel. المساهم هنا هو Pascal Baljet.

تنبيه عملي (استنتاج مني): إذا فعّلت الميزة فستصلك هذه الحقول في الواجهة كـ BigInt لا Number، فانتبه إلى الشيفرة التي تخلط النوعين في العمليات الحسابية، لأن JavaScript لا تسمح بخلط BigInt وNumber في عملية واحدة دون تحويل صريح.

إصلاحات لا تقل أهمية

يذكر المقال عددًا من الإصلاحات في هذا الإصدار:

  • استدعاءات Form المفقودة: بعض الاستدعاءات لم تكن تُمرَّر إلى الزيارات (visits)، وهي onHttpException وonNetworkError وonBeforeUpdate وonFlash. صارت تُمرَّر الآن، وإرجاع false يمنع المعالجة الافتراضية. (Dale Weaver)
  • تلف UTF-8 في SSR: أُصلح تلف الأحرف متعددة البايتات عند قراءة جسم الطلب في SSR. وهذا يهمنا نحن الذين نكتب بالعربية، فالأحرف العربية متعددة البايتات.
  • التحديثات المتفائلة (optimistic updates): الاستجابات التي تصل بترتيب خاطئ لم تعد تتراجع عن تحديث متفائل أحدث، بفضل معرّفات الطلبات.
  • التنقل في السجل (history): صارت نسخة الأصول (assets) تُقارَن، لمنع عرض props قديمة بعد نشر نسخة جديدة.

هل أرقّي؟

الترقية من 3.x إلى 3.8 إضافية بطبيعتها، فالميزتان الجديدتان اختياريتان. لكن بما أن بعض الإصلاحات تغير سلوكًا (مثل تمرير استدعاءات Form)، فاقرأ ملاحظات الإصدار وشغّل اختباراتك قبل النشر.

الخلاصة

  • WhenMounted تعطيك طريقة مقننة لعرض كود المتصفح فقط دون أخطاء SSR ودون hydration mismatch.
  • دعم BigInt يحل مشكلة دقة الأرقام الضخمة، لكنه يتطلب تفعيلًا صريحًا وانتباهًا لنوع BigInt في الواجهة.
  • إصلاح UTF-8 في SSR خبر جيد لكل من يبني واجهات عربية.

المصادر