---
title: "بناء مواقع ثابتة دون React، باستخدام React (الجزء 2/3)"
description: "إدارة ملفات Javascript وملفات الأنماط (stylesheets) وغيرها من الملفات في خط البناء مهمة صعبة. فنحن أمام أسئلة مثل: كيف نتخلص من بيئة تشغيل React داخل الـ bundle؟ وكيف نحسّن ملفات CSS؟ وكيف نتعامل مع الملفات الثابتة؟"
canonical: https://oozou.com/ar/blog/building-static-sites-without-react-using-react-part-2-3-72
locale: ar
date: 2020-07-22
author: "OOZOU Team"
---

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

> إدارة ملفات Javascript وملفات الأنماط (stylesheets) وغيرها من الملفات في خط البناء مهمة صعبة. فنحن أمام أسئلة مثل: كيف نتخلص من بيئة تشغيل React داخل الـ bundle؟ وكيف نحسّن ملفات CSS؟ وكيف نتعامل مع الملفات الثابتة؟

Published: 2020-07-22 · Author: OOZOU Team (Engineering) · 4 min read

> هذا المقال تكملة للجزء الأول من سلسلة "بناء مواقع ثابتة دون React، باستخدام React"، لذا احرصوا على قراءة الجزء الأول قبل المتابعة.

لنتحدث عن التعامل مع ملفات Javascript. إذا استخدمنا "import" التقليدية داخل ملفات المكوّنات، فسينتهي بنا الأمر إلى تجميع كل هذه الملفات في bundle واحد (وهذا جيد) مع بيئة تشغيل React (وهذا جيد أيضًا، لكننا لا نريده في هذه الحالة). ولا يوفر Webpack حاليًا طريقة سهلة لتحديد أي جزء من الـ script يجب تضمينه في الـ bundle. لذلك علينا أن نتجنب صراحةً استيراد الوحدات بشكل ثابت، وأن نلجأ إلى [الاستيراد الديناميكي (Dynamic Import)](https://webpack.js.org/guides/code-splitting/#dynamic-imports).

# التطوير أولًا

لا يمكننا استيراد الـ scripts المطلوبة ديناميكيًا في أي مكان داخل ملف المكوّن. علينا أن نفكر بمبدأ "التطوير أولًا" ونحن نرسم طريقنا. فكّروا في الوقت الذي نطوّر فيه الصفحات: يجب ألا تبدأ الـ scripts المضمّنة في كل مكوّن بالتنفيذ **إلا بعد عرض المكوّن**. فمثلًا، إذا أردنا عنوانًا يتغيّر لونه في إحدى الصفحات، فيجب أن يكون العنوان نفسه موجودًا قبل أن يبدأ script تغيير اللون. كيف نحقق ذلك؟ الجواب في الـ [**HOOK**](https://reactjs.org/docs/hooks-intro.html) (نعم، التلاعب بالكلمات مقصود)، والـ hook الذي نستخدمه هو [useEffect](https://reactjs.org/docs/hooks-reference.html#useeffect).
بعبارة أخرى، نحن في الواقع ننشئ custom hook يغلّف الـ hook المسمّى useEffect، ونسمّيه "useScripts".

```javascript
// src/useScripts.js
import { useEffect } from "react";

export function useScripts(scriptLoaders) {
  useEffect(() => {
    loadScripts(scriptLoaders);
  });
}

// Each dynamic import is asynchronous
async function loadScripts(scriptLoaders) {
  for (const load of scriptLoaders) {
    await load();
  }
}
```

# التطوير باستخدام Storybook

سنستخدم في هذا المشروع [Storybook](https://storybook.js.org/) للتطوير. لنجهّزه (قد يستغرق ذلك بعض الوقت).

```
npx -p @storybook/cli sb init
```

لنحذف ملفات stories المولّدة تلقائيًا، وننشئ stories لصفحتي Home وAboutUs.

```javascript
// stories/pages.stories.js
import React from "react";

import Home from "../pages/Home";
import AboutUs from "../pages/AboutUs";

export default { title: "Pages" };

export { Home, AboutUs };
```

الآن يُفترض أن يبدو هيكل المشروع هكذا

```
├── pages
│   ├── AboutUs.jsx
│   └── Home.jsx
├── scripts
│   └── build.js
├── src
│   └── useScripts.js
├── stories
│   └── pages.stories.js
├── babel.config.js
├── package.json
└── webpack.config.js
```

الآن شغّلوا

```
yarn storybook
```

ثم ننتقل إلى [localhost:6006](http://localhost:6007/?path=/story/pages--home)
لننشئ الـ scripts، وهي: src/home.js وsrc/about-us.js

```javascript
// home.js
console.log("home.js");

const title = document.getElementById("home");

let cyan = true;

title.style.transition = "color 0.5s";

setInterval(() => {
  title.style.color = cyan ? "cyan" : "black";
  cyan = !cyan;
}, 1000);
```
```javascript
//about-us.js
console.log("about-us.js");
```

والآن لنستوردهما عبر useScripts.

```javascript
//Home.jsx
import React from "react";
import { useScripts } from "../src/useScripts";

const Home = () => {
  useScripts([() => import("../src/home")]);
  return <h1 id="home">Home Page</h1>;
};

export default Home;
```
```javascript
import React from "react";
import { useScripts } from "../src/useScripts";

const AboutUs = () => {
  useScripts([() => import("../src/about-us")]);
  return <h1>About Us</h1>;
};

export default AboutUs;
```

كما ترون، نتوقع بعد الدخول إلى صفحة Home أن يُنفَّذ home.js ويغيّر لون العنوان كل ثانية.
وها هو يعمل!

# ملفات الأنماط (Stylesheets)

ذكرت أن عبارات import العادية تجلب معها بيئة تشغيل React، لكن استيراد ملفات الأنماط والملفات الثابتة لا يفعل ذلك، لذا يمكننا استيرادها بالطريقة المعتادة.
لننشئ الملف pages/Home.css ونعدّل الملفات المرتبطة به.

```css
// Home.css
#home {
  transition: color 0.2s;
}
```
```javascript
// Home.jsx
import React from "react";
import { useScripts } from "../src/useScripts";

import "./Home.css"; // import stylesheets

const Home = () => {
  useScripts([() => import("../src/home")]);
  return <h1 id="home">Home Page</h1>;
};

export default Home;
```

ويمكننا أيضًا حذف سطر الـ transition المكتوب بأسلوب أمري (imperative) في home.js

```javascript
// home.js
console.log("home.js");

const title = document.getElementById("home");

let cyan = true;

// title.style.transition = "color 0.5s"; <-- remove this

setInterval(() => {
  title.style.color = cyan ? "cyan" : "black";
  cyan = !cyan;
}, 1000);
```

وهذا كل ما يتعلق بالتطوير تقريبًا. سنتوقف هنا الآن. لم نتحدث بعد عن عملية البناء التي تنتج ملفات HTML وJS وCSS النهائية، فتابعونا في الجزء التالي!

---

Contact OOZOU: hello@oozou.com · +66 2544 0000 · https://oozou.com/ar/contact

More for AI agents: https://oozou.com/llms.txt · every page has a markdown twin at its URL plus ".md"
