المحطّة ٨: النشر والتسليم
الخطوة الأخيرة: طبقتان تعملان على خادمٍ حقيقيّ، موثّقتان يشغّلهما غيرك. ⏱ نحو 22 دقيقة.
- تنشر تطبيق
React+Expressمن طبقتين. - تنقل الأسرار والعناوين إلى متغيّرات بيئة.
- تضبط
CORSوإعدادات الإنتاج الآمنة. - تجهّز توثيقًا يمكّن غيرك من تشغيل المنتج.
١نشر تطبيقٍ من طبقتين
مشروعنا طبقتان لهما طريقتا تشغيلٍ مختلفتان في التطوير: الواجهة على خادم Vite، والخادم على Node. عند النشر — كما تعلّمت في 242 — نحوّلهما إلى منتجٍ واحدٍ يعمل على خادمٍ حقيقيّ.
- ابنِ الواجهة:
npm run buildيُنتج ملفّات ثابتة(HTML/CSS/JS)فيdist/. - شغّل الخادم:
node server.jsعلى منفذٍ ثابت، ويقدّم الـ API تحت/api. - اربطهما: إمّا أن يقدّم Express ملفّات
dist/نفسه، أو تُنشَر الواجهة على استضافةٍ ثابتةٍ والخادم على مزوّد Node.
٢إعدادات الإنتاج الحرجة
| الإعداد | في التطوير | في الإنتاج |
|---|---|---|
| عنوان الـ API | localhost:3000 | متغيّر بيئةٍ VITE_API_URL |
| السرّ JWT | نصٌّ ثابت | متغيّر بيئةٍ طويلٌ عشوائيّ، خارج الكود |
| CORS | مفتوحٌ للتطوير | مقصورٌ على أصل الواجهة فقط |
| الأخطاء | مفصّلةٌ في الطرفية | رسالةٌ عامّةٌ للمستخدم، وتفصيلٌ في السجلّ |
| HTTPS | اختياريّ | مطلوبٌ (الرموز تُرسَل عبر الشبكة) |
٣CORS: لماذا قد تُرفَض طلبات واجهتك؟
حين تكون الواجهة على أصلٍ (origin) والخادم على آخر، يحجب المتصفّح الطلبات افتراضيًّا. الحلّ أن يأذن الخادم صراحةً لأصل الواجهة:
const cors = require('cors');app.use(cors({ origin: process.env.WEB_ORIGIN })); // أصل الواجهة فقط، لا '*'
في التطوير يكفي وكيل Vite؛ في الإنتاج اضبط CORS بدقّةٍ على أصل واجهتك وحده — لا *، فذلك يفتح الـ API للجميع.
٤حزمة التسليم
- كود الطبقتين منظّمًا (مجلّد
clientوserver). - ملفّ
.env.exampleيوضّح المتغيّرات المطلوبة (بلا قيَمٍ حقيقيّة). - ملفّ
README: خطوات التثبيت والتشغيل (npm install، البناء، التشغيل)، وبيانات دخولٍ تجريبيّة. - وثائق المحطّات: المتطلّبات، وعقد الـ
API، وخطة الاختبار.
حين يشغّل زميلٌ مشروعك من README وحده — واجهةً وخادمًا — فقد صار «منتجًا». هذا معنى «من الفكرة إلى المنتج».
توقّع وتحقّق
أين يوضع عنوان الـ API للإنتاج؟
ضبط CORS الصحيح في الإنتاج:
ماذا يُنتج npm run build؟
لماذا سرّ JWT خارج الكود؟
الخلاصة
- النشر: ابنِ الواجهة
(dist)، شغّل الخادم، واربطهما (تقديمٌ ذاتيٌّ أو استضافتان). - الإنتاج: عنوان
APIومفاتيح في متغيّرات بيئة، لا في الكود. CORSفي الإنتاج مقصورٌ على أصل الواجهة، لا *.- أخفِ تفاصيل الأخطاء عن المستخدم، وسجّلها داخليًّا، واستعمل
HTTPS. - حزمة التسليم: كودٌ + .
env.example + README+ عقدAPI+ خطة اختبار.
تحدٍّ تصميمي: نشر نظام الحجز وتسليمه
تصميميانشر مشروعك (واجهةً وخادمًا) وجهّز حزمة تسليمٍ كاملة بحيث يشغّله زميلٌ من الصفر باتّباع توثيقك وحده.
- بناء الواجهة وتشغيل الخادم معًا.
- نقل الأسرار والعناوين إلى متغيّرات بيئة.
- ضبط CORS للإنتاج، وإخفاء تفاصيل الأخطاء.
- README و .env.example ووثائق المحطّات.
💡 تلميح 1
import.meta.env.VITE_API_URL.