OOZOU
تواصلوا معنا
العودة إلى المدونة

بناء مواقع ثابتة دون React، باستخدام React (الجزء 1/3)

React رائعة ونحب العمل بها، لكننا ببساطة لا نريدها داخل ملفات HTML وCSS وJavascript النهائية.

20 يوليو 2020
3 دقائق للقراءة
بناء مواقع ثابتة دون React، باستخدام React (الجزء 1/3)

نحن في عام 2020، والحديث يتزايد عن توليد المواقع الثابتة (static site generation) باستخدام أطر الواجهات مثل React. ولدينا مكتبات جيدة كثيرة، بل أطر عمل كاملة، مثل Gatsby وNextJS وreact-static وغيرها.

لماذا إذن نتحدث عن طريقة أخرى لتوليد المواقع الثابتة بدل استخدام هذه الأدوات الرائعة الموجودة؟

في الأساس، تنشئ كل هذه الأدوات ملفات HTML وCSS وJavascript ثابتة، لكنها تترك فيها بصمات React. وهذا ليس أمرًا سيئًا على الإطلاق، بل هو أفضل ما حدث على الإطلاق. فأنتم تحصلون على بيئة تشغيل React ومعها فوائد virtual DOM. لكن تخيّلوا أننا مطالبون بإنشاء ملفات HTML تقليدية بسيطة، مع بعض منطق الواجهة في script يعمل على جهة العميل. يمكننا استخدام كثير من محركات القوالب (template engines) المتاحة، لكن لماذا لا نستخدم React؟

نظرة عامة

منذ أن قدّمت React الدالة renderStaticMarkup، يستخدمها كثيرون للعرض من جهة الخادم (server-side rendering) وإخراج HTML بسيط، وهذه فكرة أنيقة. سنستخدمها لتوليد المحتوى المُعرَض مسبقًا (pre-rendered). ثم نستخرج ملفات CSS وJavascript المرتبطة به. وأخيرًا نضع المحتوى المُعرَض مسبقًا داخل قالب HTML مع وسوم script وstylesheet الصحيحة، ونُخرج الملفات.

الإعداد

لنبدأ بملف package.json

{
  "name": "react-no-react",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "react": "^16.9.0",
    "react-dom": "^16.9.0"
  },
  "devDependencies": {
    "@babel/cli": "^7.8.4",
    "@babel/core": "^7.10.4",
    "@babel/node": "^7.10.4",
    "@babel/preset-env": "^7.9.5",
    "@babel/preset-react": "^7.9.4",
    "glob": "^7.1.6"
  }
}

كما ترون، نحتاج إلى React وReactDOM وBabel. نستخدم Babel لتحويل (transpile) كود Javascript الذي قد نكتبه بصيغة ES6 للعمل على جهة العميل. وسنستخدم babel-node أيضًا كأداة CLI. لننشئ هيكل المشروع.

.
├── pages
│   ├── AboutUs.jsx
│   └── Home.jsx
├── scripts
│   └── build.js
├── babel.config.js
└── package.json

في ملف babel.config.js ننشئ الإعداد على هذا النحو

module.exports = {
  presets: ["@babel/env", "@babel/react"],
};

ثم في ملف scripts/build.js.

import React from "react";
import path from "path";
import fs from "fs";
import glob from "glob";
import { renderToStaticMarkup } from "react-dom/server";
import { spawnSync } from "child_process";

const cwd = path.resolve(__dirname, "..");

// We glob all the files under "pages" directory
const reactFiles = glob.sync("pages/**/*.jsx", { cwd });

reactFiles.forEach((reactFile) => {
  const fileName = path.basename(reactFile).replace(".jsx", "");

  // Page components are from "default" export
  const Component = require(path.resolve(__dirname, "../", reactFile)).default;
  const staticMarkup = renderToStaticMarkup(<Component />);

  // Generate HTML file name from ".jsx" files by replacing the extension with ".html"
  const htmlFile = path.resolve(
    __dirname,
    "../dist/",
    reactFile.replace(".jsx", ".html")
  );

  const dirName = path.dirname(htmlFile);

  // In case we have nested page structure, we need to create directory recursively.
  fs.mkdirSync(dirName, { recursive: true });

  fs.writeFileSync(
    htmlFile,
    `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>${fileName}</title>
</head>
<body>
  ${staticMarkup}
</body>
</html>`,
    "utf8"
  );
});

لننشئ الصفحات

// pages/Home.jsx
import React from "react";

export default () => <h1>Home Page</h1>;
// pages/AboutUs.jsx
import React from "react";

export default () => <h1>About Us</h1>;

وأخيرًا، أنشئوا script للبناء داخل package.json

...
"scripts": {
  "build": "babel-node scripts/build.js"
},
...

شغّلوا الـ script

npm run build

أو

yarn build

بعد ذلك يُفترض أن تروا ملفين جديدين.

.
├── dist
│   ├── AboutUs.html
│   └── Home.html
...

لكن هذه مجرد ملفات HTML بسيطة. فماذا عن CSS وJS والملفات الثابتة (static assets)؟ هذا ما سنناقشه في الجزء التالي، فإن كان الموضوع يهمكم، تابعونا.اقرأوا التالي: بناء مواقع ثابتة دون React، باستخدام React (الجزء 2/3)

Related Articles

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

كيف أصمّم برمجيات؟ دليل المبتدئين لأصحاب الأعمال

تصميم البرمجيات عملية ممتعة لكنها معقدة، تتطلب الإبداع والتفكير المنطقي ومهارات حل المشكلات.

اقرأوا المزيد
مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

مستقبل الحوسبة الطرفية: ما تحتاج الشركات إلى معرفته

يتطور المشهد الرقمي بسرعة، وعلى الشركات أن تتكيّف لتواكب الطلب المتزايد على السرعة والكفاءة والمعالجة في الوقت الفعلي.

اقرأوا المزيد
مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

مستقبل قطاع التجزئة: الذكاء الاصطناعي والواقع المعزّز واتجاهات التحوّل الرقمي

يتطور قطاع التجزئة بوتيرة غير مسبوقة بفضل الذكاء الاصطناعي (AI) والواقع المعزّز (AR) وتقنيات التحوّل الرقمي. فلم تعد المتاجر التقليدية مجرد أماكن لبيع المنتجات، بل أصبحت متاجر ذكية وتفاعلية.

اقرأوا المزيد

Have a Project in Mind?

Let's discuss how we can help bring your ideas to life with our expertise in web and mobile development.

ابدأوا المحادثةhello@oozou.com
OOZOU Logo

بانكوك · سنغافورة · هونغ كونغ

X
Facebook
Instagram
LinkedIn
OOZOU Co., Ltd.
548 One City Centre
Ploenchit Road
Bangkok 10330
Thailand
+66 2544 0000
hello@oozou.com

الخدمات

  • تطوير الويب
  • وكلاء الذكاء الاصطناعي والذكاء الاصطناعي التوليدي
  • تطوير تطبيقات الجوال
  • تحليلات البيانات وهندستها
  • تصميم تجربة المستخدم وواجهته (UX/UI) وتصميم المنتجات
  • التحوّل الرقمي

الشركة

  • من نحن
  • الوظائف
  • المدونة
  • دراسات الحالة
  • عروض حية
  • تعلّمت اليوم
  • تواصل معنا

المزيد

  • القطاعات
  • شبكة الشركاء
© 2026 OOZOU. جميع الحقوق محفوظة.
سياسة الخصوصيةمدونة قواعد السلوكسياسة مكافحة الرشوة والفساد