3.2محركات القوالب وخدمة الملفات
الأساسي في 30 ثانية
- الثابت يُقدَّم بسطر واحد : app.use(express.static('public')) يقدم CSS والصور و JS العميل من مجلد مخصص.
- الديناميكي يُصيَّر بمحرك : قوالب EJS/Handlebars/Pug + res.render('vue', { données }) = HTML مُجمَّع جهة الخادم (SSR).
- بنيتان صالحتان : SSR للمحتوى وتحسين الظهور (SEO)، و API JSON + واجهة منفصلة للتطبيقات التفاعلية — والمستويات التالية تميل نحو الـ API.
حالة مصغرة متسلسلة — ساليم ينشر الفهرس SSR ثم API
ساليم، مطور مبتدئ في الجزائر، عليه نشر الفهرس : بطاقات منتجات بـ HTML لأجل الفهرسة، إضافة إلى لوحة متابعة داخلية شديدة التفاعل. يقدم أولا CSS والصور مع express.static('public')، ويضبط EJS (app.set('view engine', 'ejs')) ويصير res.render('produit', { produit }) لبطاقات SSR. وللوحة المتابعة، يعرض البيانات نفسها بـ res.json() : ستستهلك الواجهة المخصصة الـ API. خادم واحد، وعرضان حسب الاستعمال.
هذه الحالة نفسها تعود في الدرس والمخطط والنص الجاهز وتحدي 48 ساعة.
1. الملفات الثابتة والقوالب
يقدم تطبيق الوب موارد ثابتة (CSS والصور و JS العميل والخطوط) : يقدمها إكسبريس بالوسيط الأصلي express.static() — app.use(express.static('public')) يعرض كل مجلد public/ (طلب نحو /style.css يرجع public/style.css). نجمع الأصول في هذا المجلد المخصص.
ولأجل HTML الديناميكي، نستعمل محرك قوالب (template engine) : قالب (HTML + متغيرات وحلقات وشروط) يُملأ ببيانات. الشائعة : EJS (JS داخل وسوم <% %>، قريب من HTML)، و Handlebars/hbs (بصيغة {{ }}، مُنقاة)، و Pug (بالإزاحة، موجزة). نضبط (app.set('view engine', 'ejs'))، ونرتب العروض في views/، ونصير مع res.render('page', { données }). وهذا هو SSR (التصيير جهة الخادم) : يبني الخادم HTML كاملا ويرسله للمتصفح.
2. SSR أو API + واجهة منفصلة : التحكيم حسب المشروع
يناسب SSR مواقع المحتوى (الواجهات والمدونات والتجارة الكلاسيكية)، و SEO (HTML جاهز، جيد الفهرسة) و التحميل الأولي السريع. والبديل العصري : يعرض نود API REST بـ JSON (القسم 4-1) تستهلكها واجهة منفصلة (React و Vue و Angular) تعرض جهة المتصفح — مثالي للتطبيقات التفاعلية (لوحات المتابعة والأدوات) والتجربة السلسة دون إعادة تحميل.
وكلتاهما صالحة : يختار ساليم SSR للبطاقات (المحتوى و SEO) و API + واجهة للوحة المتابعة (التفاعلية). وليس SSR متجاوَزا : بل يعود بقوة عبر Next.js/Nuxt اللذين يجمعان تصيير الخادم والتفاعلية. والمستويات التالية تميل نحو مقاربة API/JSON، الغالبة جهة نود.
🔎 مثال ملموس — التقديم ثم التصيير، ثم العرض JSON
يغطي ساليم المخارج الثلاثة بالخادم نفسه.
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.get('/produits/:id', (req, res) => {
res.render('produit', { produit: { id: req.params.id } });
});
app.get('/api/produits/:id', (req, res) => {
res.json({ id: req.params.id });
});
القراءة : نفس البيانات، وعرضان : HTML عبر EJS أو JSON عبر res.json().
الدرس : مقارنة العرضين تُشعر بالفرق بين SSR و API.
مفردات القسم
- الملفات الثابتة
- موارد ثابتة (CSS والصور و JS العميل والخطوط) تُقدَّم كما هي بـ express.static('public').
مثال بسيط: الـ style.css الخاص بساليم مقدم من public/.
ما ليس كذلك: عرض EJS مصيَّر ببيانات.
رد فعل: تجميع كل الأصول في public/.
- محرك القوالب
- أداة تولد HTML ديناميكيا من قوالب (متغيرات وحلقات وشروط) : EJS و Handlebars و Pug.
مثال بسيط: بطاقة منتج EJS الخاصة بساليم التي تحلق على الآراء.
ما ليس كذلك: مجرد مجلد ملفات ثابتة.
رد فعل: اختيار EJS للبدء، لقربها من HTML.
- res.render()
- طريقة إكسبريس تصير عرضا : res.render('page', { données }) تحقن البيانات في قالب views/.
مثال بسيط: res.render('produit', { produit }) عند ساليم.
ما ليس كذلك: إرسال JSON خام للواجهة.
رد فعل: تسمية العرض باسم ملف views/.
- SSR
- التصيير جهة الخادم : يولد الخادم HTML كاملا ويرسله للمتصفح ؛ وميزته المحتوى و SEO.
مثال بسيط: بطاقات فهرس ساليم القابلة للفهرسة.
ما ليس كذلك: SPA تصير كل شيء في المتصفح.
رد فعل: تفضيل SSR للصفحات المراد فهرستها.
- API + واجهة منفصلة
- يعرض نود JSON (API REST) تستهلكه واجهة React/Vue/Angular تعرض جهة المتصفح.
مثال بسيط: لوحة المتابعة الداخلية المغذاة بـ res.json().
ما ليس كذلك: قالب EJS مصيَّر جهة الخادم.
رد فعل: حصر هذه البنية في التطبيقات التفاعلية.
في التطبيق — خدمة الملفات وتوليد HTML
- اخدموا ملفات ثابتة مع app.use(express.static('public')) : ضعوا CSS وصورة في public/ وتحققوا من الوصول إليهما.
- اضبطوا محرك قوالب (مثلا EJS : app.set('view engine', 'ejs')) وضعوا القوالب في views/.
- صيروا عرضا ببيانات : res.render('page', { titre: '...', items: [...] }) ؛ وفي القالب، أدخلوا المتغيرات وحلقوا على قائمة.
- قارنوا : صيروا البيانات نفسها JSON (res.json(data)، مقاربة API) لإدراك الفرق بين SSR و API + واجهة منفصلة.
نص جاهز للقول — تبرير SSR مقابل API (30 ثانية)
« بطاقات الفهرس تنطلق SSR مع EJS : HTML كامل، جيد لـ SEO والعرض الأول. ولوحة المتابعة، شديدة التفاعل، تستهلك البيانات نفسها JSON عبر الـ API خاصتنا. والثابت CSS والصور مقدم بـ express.static من public. »
يُقال في تحكيم البنية ؛ وتُعرَض البيانات نفسها HTML ثم JSON.
نموذج نسخ-لصق — ثابت + EJS + JSON
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.get('/produits/:id', (req, res) => {
res.render('produit', { id: req.params.id });
});
app.get('/api/produits/:id', (req, res) => {
res.json({ id: req.params.id });
});
app.listen(3000);
مستقل
يكفي موقع واجهة SSR + ثابت : لا واجهة ثقيلة لصفحات قليلة.
مقاولة صغيرة في الجزائر
يصير ساليم البطاقات EJS لأجل SEO ويبقي API JSON للإدارة الداخلية.
فريق منتج
الفصل بين views/ (SSR) و /api (JSON) ليتقدم فريقان دون تعارض.
مبتدئ
هذا الأسبوع : CSS مقدم ثابتا وعرض EJS واحد بحلقة على ثلاثة عناصر.
✓ ممارسات جيدة
- خدمة الأصول مع express.static (مجلد public واحد).
- اختيار البنية حسب المشروع (المحتوى/SEO مقابل التطبيق التفاعلي).
- إتقان API REST (JSON) : المقاربة الغالبة في المستويات التالية.
✗ أخطاء شائعة
- اعتقاد SSR « متجاوَزا » (وهو يعرف نهضة : Next.js/Nuxt).
- اختيار SPA لموقع محتوى بسيط (تعقيد عديم الفائدة).
- إهمال SEO في بنية SPA خالصة.
النقاط الأساسية
- الخدمة الثابتة : app.use(express.static('public')) يقدم الموارد الثابتة (CSS والصور و JS العميل).
- محركات القوالب (EJS و Handlebars و Pug) : HTML ديناميكي عبر res.render('vue', {données}).
- SSR : يولد الخادم HTML كاملا — مقاربة المواقع الكلاسيكية (المحتوى و SEO).
- البديل العصري الشائع جدا : يعرض نود API REST (JSON) تستهلكها واجهة منفصلة (React/Vue/Angular).
تحدي 48 ساعة — طبّق غدا
اخدموا CSS واحدا ثابتا وصيروا عرض EJS واحدا مع حلقة على 3 عناصر.
- أخدم مجلد public/ دون تردد.
- أصير عرضا مع res.render().
- أحكم بين SSR و API حسب المشروع.
أسئلة شائعة
SSR (قوالب) أو API + واجهة منفصلة : أي بنية نختار ؟
كلتاهما صالحة حسب المشروع. يناسب SSR مواقع المحتوى (المدونات والواجهات والتجارة الكلاسيكية)، عندما يهم SEO (HTML مقدم جاهزا)، ولأجل تحميل أولي سريع والمواقع قليلة التفاعل (أبسط). وتناسب API + واجهة منفصلة التطبيقات التفاعلية (لوحات المتابعة والأدوات)، و التجربة السلسة دون إعادة تحميل و الفصل بين الواجهة والخلفية. ينوع ساليم : SSR للبطاقات، و API للوحة المتابعة.
هل التصيير جهة الخادم متجاوز أمام React ؟
لا، بل يعرف نهضة. فبعد عهد SSR الكلاسيكي (قوالب EJS)، ثم حماس SPA (كل شيء مصيَّر جهة العميل، بحدود SEO والتحميل الأولي)، تجمع أطر مثل Next.js و Nuxt بين الاثنين : HTML مصيَّر خادميا (SEO والسرعة) + تفاعلية العميل (تجربة SPA). ويبقى SSR الكلاسيكي وجيها لمواقع كثيرة ببساطته.
أي طريقة إكسبريس تصير عرضا ببيانات ؟