Skip to content

مديروا الحزم

💡 دليل التعلم: لكتابة الكود لا داعي لإعادة اختراع العجلة — 99% من الوظائف كتبها آخرون ونشروها على الإنترنت. مدير الحزم هو الأداة التي تساعدك في إيجاد وتحميل وإدارة تلك "القطع الجاهزة". يدور هذا الفصل حول سؤال محوري: كيف نجعل تبعيات الكود قابلة للتكرار والتعاون والصيانة؟


0. لماذا ستستخدم مدير حزم حتماً؟

تخيل أنك تريد كتابة برنامج Node.js يمكنه إرسال طلبات HTTP. أمامك طريقان:

  • الطريقة أ (يدوية): تنفذ بنفسك اتصال TCP، وتحليل بروتوكول HTTP، ومعالجة إعادة التوجيه، وآلية المهلة... ربما آلاف الأسطر وأشهر من التصحيح.
  • الطريقة ب (مدير حزم): npm install axios، في عشر ثوانٍ وسطر واحد.

مدير الحزم هو في جوهره "متجر التطبيقات للكود". يساعدك في:

  1. إيجاد المكتبات التي نشرها آخرون في سجل مركزي (Registry)
  2. تنزيلها وتثبيتها تلقائياً في مشروعك
  3. إدارة تبعيات تلك المكتبات (تبعيات التبعيات)
  4. تسجيل النسخة الدقيقة التي تستخدمها لضمان عدم وجود مشاكل في عمل الفريق

1. نظرة عامة على مديري الحزم حسب النظام البيئي/اللغة

لغات البرمجة وأنظمة التشغيل المختلفة لها سلاسل أدوات خاصة، لكن المنطق الأساسي متطابق.

👇 جرّب: اختر النظام البيئي الذي تعرفه واستكشف أدواته الرئيسية.

Package Manager Ecosystem MapChoose a language ecosystem and explore its package management tools
npm
Most widely used and bundled with Node.js
Yarn
Fast parallel downloads; Plug'n'Play can avoid node_modules
pnpm
Shared hard links save disk space and make installs fast
npmNode Package Manager
Install dependencynpm install lodash
Install dev dependencynpm install -D typescript
Run scriptnpm run build
List installednpm list --depth=0
package.jsonProject manifest that records dependencies and scripts
package-lock.jsonPins exact versions for consistent environments
node_modules/Directory where installed packages live
Built into Node.js
Largest ecosystem, 2M+ packages
Supports workspaces
Run directly with npx
Core idea:A package manager is like an app store for code. It downloads, installs, and manages libraries written by others while automatically handling version compatibility.

1.1 من أين تُنزّل الحزم؟ — السجل (Registry)

كل نظام بيئي لديه سجل مركزي يخزن جميع الحزم المتاحة للتنزيل:

النظام البيئيالسجلعدد الحزم
JavaScriptnpmjs.com2 مليون+
Pythonpypi.org500 ألف+
Rustcrates.io150 ألف+
Gopkg.go.dev500 ألف+
أدوات macOS/Linuxformulae.brew.sh7000+
برامج Windowswinget.run / chocolatey.orgعشرات الآلاف

1.2 مقارنة رواد JavaScript الثلاثة: npm vs yarn vs pnpm

وظائف مشابهة، والفروق بشكل رئيسي في السرعة واستخدام القرص:

text
استخدام القرص: pnpm (روابط صلبة مشتركة) < yarn PnP (بدون node_modules) < npm (نسخ كاملة)
سرعة التثبيت: pnpm ≈ yarn > npm
عادات الاستخدام: npm (الأكثر شيوعاً) > pnpm (موصى به للمشاريع الجديدة) > yarn (بعض الفرق)

التوصية: استخدم pnpm في المشاريع الجديدة؛ حافظ على الأداة الحالية في المشاريع القائمة، دون تبديل عشوائي.

1.3 مقارنة رواد Windows الثلاثة: winget vs Chocolatey vs Scoop

wingetChocolateyScoop
الدعم الرسميMicrosoft رسميطرف ثالثطرف ثالث
يحتاج مديرجزئياًنعملا
مناسب لـتثبيت البرامج اليومينشر المؤسسات الكبيرإدارة أدوات التطوير
عدد الحزمكثير وينمو بسرعةالأكثر (10000+)مركز على أدوات التطوير

التوصية: winget للاستخدام اليومي، scoop لأدوات التطوير، Chocolatey للأتمتة المؤسسية.


2. تثبيت حزمة — ماذا يحدث خلف الكواليس؟

تكتب npm install axios، يصمت سطر الأوامر لبضع ثوانٍ ثم ينتهي. ماذا حدث في تلك الثواني؟

👇 جرّب: اختر حزمة وانقر على "تشغيل" لمراقبة عملية التثبيت بالكامل.

Full npm install SimulationWatch a package travel from the command line to disk
$ npm install
📟 Install log
Waiting to run...
📁 File tree changes
my-project/
├── package.json
├── package-lock.json
└── node_modules/
📄 package.json
{
  "name": "my-project",
  "version": "1.0.0",
  "dependencies": {},
  "devDependencies": {}
}
Resolve deps
Analyze required packages
Fetch & extract
Download tarballs from registry
Link modules
Write node_modules/
Write lockfile
Pin exact versions
Core mechanism:Installation first resolves the dependency tree, downloads from the registry, extracts packages into node_modules, and writes a lockfile. The lockfile ensures everyone on the team installs the exact same versions.

2.1 المراحل الأربع بالتفصيل

① حل التبعيات (Resolve)

يقرأ المدير أولاً ما تريد تثبيته. مثلاً axios يعتمد على follow-redirects و form-data وغيرها، وهذه يجب تثبيتها أيضاً. هذه العملية تُسمى بناء شجرة التبعيات.

② التنزيل (Fetch)

تنزيل جميع الحزم المطلوبة من السجل (ملفات مضغوطة .tgz). المديرون الذكيون:

  • ينزلون عدة حزم بالتوازي بدلاً من الانتظار واحداً تلو الآخر
  • يفحصون ذاكرة التخزين المؤقت المحلية أولاً؛ إذا وُجدت لا يستخدمون الشبكة

③ الربط (Link)

فك ضغط الحزم المنزّلة ووضعها في دليل node_modules/ ومعالجة علاقات المرجعية.

④ كتابة ملف القفل (Lockfile)

تسجيل أرقام النسخ الدقيقة لهذا التثبيت في package-lock.json (أو yarn.lock / pnpm-lock.yaml).

2.2 مرجع سريع للأوامر الأكثر استخداماً

bash
# ── JavaScript (npm) ──────────────────────────────────
npm install              # تثبيت جميع التبعيات حسب package.json
npm install axios        # تثبيت حزمة جديدة (تبعية إنتاج)
npm install -D jest      # تثبيت تبعية تطوير (فقط أثناء التطوير)
npm install -g tsx       # تثبيت عام (متاح في أي مجلد)
npm uninstall axios      # إلغاء تثبيت الحزمة
npm update               # ترقية جميع الحزم للنسخة المتوافقة الأحدث
npm run build            # تشغيل السكربتات في package.json
npx create-react-app .   # تشغيل مؤقت دون تثبيت في المشروع

# ── Python (pip) ──────────────────────────────────────
pip install requests           # تثبيت حزمة
pip install requests==2.28.0   # تثبيت نسخة محددة
pip freeze > requirements.txt  # تصدير قائمة التبعيات الحالية
pip install -r requirements.txt # تثبيت حسب القائمة

# ── Rust (cargo) ──────────────────────────────────────
cargo add serde    # إضافة تبعية (يُحدّث Cargo.toml تلقائياً)
cargo build        # بناء المشروع
cargo test         # تشغيل الاختبارات
cargo run          # تشغيل المشروع

# ── Go (go mod) ───────────────────────────────────────
go get github.com/gin-gonic/gin  # إضافة تبعية
go mod tidy                      # تنظيف التبعيات
go build ./...                   # بناء

# ── Windows (winget) ──────────────────────────────────
winget install Git.Git           # تثبيت برنامج
winget upgrade --all             # تحديث جميع البرامج المثبتة

2.3 ما هي npm scripts؟

يوجد في package.json حقل scripts وهو مشغّل المهام المدمج في npm:

json
{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "test": "jest",
    "lint": "eslint src/"
  }
}

طريقة التشغيل: npm run dev، npm run build. الفوائد:

  • مدخل موحد: أعضاء الفريق لا يحتاجون لحفظ الأوامر المحددة لكل أداة
  • تهيئة تلقائية للبيئة: عند التشغيل يُضاف node_modules/.bin تلقائياً إلى PATH

3. التثبيت العام مقابل التثبيت المحلي

هذا من أكثر المفاهيم إرباكاً للمبتدئين.

3.1 الفروقات

bash
npm install axios        # محلي: يُثبّت في ./node_modules/، فقط المشروع الحالي يمكنه استخدامه
npm install -g typescript  # عام: يُثبّت في دليل النظام، أي مشروع/مجلد يمكنه استخدامه
التثبيت المحليالتثبيت العام
الموقع./node_modules/دليل على مستوى النظام (مثل /usr/local/lib/)
مناسب لـمكتبات يعتمد عليها المشروع (axios, vue, react)أدوات CLI (tsc, eslint, create-react-app)
عزل النسخكل مشروع بنسخة مستقلة ✅نسخة واحدة مشتركة على كل الجهاز ⚠️
اتساق الفريقملف القفل يضمن الاتساق ✅قد تختلف النسخة لدى كل شخص ⚠️

3.2 القاعدة الذهبية

تبعيات المكتبات (axios, lodash, vue) تُثبّت دائماً محلياً؛ أدوات CLI (tsc, eslint) يُفضل تثبيتها محلياً واستدعاؤها بـ npx.

لماذا يُنصح بتثبيت أدوات CLI محلياً أيضاً؟

إذا ثبّتَ eslint@8 عاماً، لكن المشروع أ يحتاج قواعد eslint@9 الجديدة، عليك التبديل بين العام والمشروع. ثبّت eslint محلياً واستخدم npx eslint .، وسيتمكن كل مشروع من تهيئة نسخته الخاصة بشكل مستقل.

3.3 npx — تشغيل مؤقت دون تلويث البيئة

npx هو مشغّل حزم مدمج في npm يتيح لك تشغيل حزمة دون تثبيتها:

bash
# دون تثبيت create-vue، شغّله مباشرة لتهيئة مشروع
npx create-vue my-project

# دون تثبيت prettier، نسّق الملفات مباشرة
npx prettier --write src/

# إجبار استخدام نسخة محددة (تجاهل المثبتة)
npx typescript@5.4 tsc --version

Python عبر uvx وRust عبر cargo run يوفران قدرة "التشغيل المؤقت" المشابهة:

bash
uvx ruff check .       # Python: تشغيل مؤقت لفاحص ruff
cargo install ripgrep  # Rust: تثبيت عام، يصبح أمر النظام rg

4. سر أرقام النسخ — الإصدار الدلالي

ستجد في package.json محتوى مثل:

json
{
  "dependencies": {
    "axios": "^1.6.8",
    "typescript": "~5.4.0"
  }
}

ماذا يعني ^ و ~؟

👇 جرّب: مرر المؤشر فوق أجزاء رقم النسخ لفهم معانيها؛ انقر على رموز النطاق لمعرفة أي النسخ ستُقبل.

Dependency Tree & Version SemanticsUnderstand semantic versions and dependency graphs
2
MAJOR
8
MINOR
3
PATCH
..
← Hover over a number to inspect its meaning
Common version range symbols
^2.8.3
Compatible range (recommended)
Allow MINOR and PATCH upgrades, lock MAJOR
~2.8.3
Approximate range (conservative)
Allow only PATCH upgrades, lock MAJOR and MINOR
2.8.3
Exact version (strict)
Accept only this one version
*
Any version (dangerous)
Accept any version, including major upgrades; avoid in production
Golden rule:Semantic versioning = MAJOR.MINOR.PATCH. A MAJOR change means breaking changes, so upgrade carefully.

4.1 لماذا لا نُثبّت النسخة بالضبط؟

النهجالميزةالعيب
"axios": "1.6.8" (تثبيت دقيق)قابل للتنبؤ تماماًتصحيحات الأمان لا تُحدّث تلقائياً
"axios": "^1.6.8" (نطاق متوافق، موصى به)يحصل تلقائياً على إصلاحات الأخطاء والميزات الجديدةنادراً قد يُدخل عدم توافق بسيط
"axios": "*" (أي نسخة)دائماً الأحدثترقية النسخة الرئيسية قد تُكسر الكود تماماً

أفضل ممارسة: أعلن عن النطاق بـ ^ + ملف القفل لتثبيت النسخة الفعلية، واستخدمهما معاً.

4.2 ما هو "جحيم التبعيات"؟

عندما تعتمد على 50 حزمة وكل حزمة تعتمد على عدة أخرى، قد يكون "شجرة التبعيات" مئات العقد. إذا حزمتان تعتمدان على نسخ غير متوافقة من نفس المكتبة، ينشأ "تعارض تبعيات".

حلول كل نظام بيئي:

  • npm v3+: يرفع للقمة النسخ من نفس النسخة الرئيسية؛ نسخ رئيسية مختلفة تُثبّت كل على حدة
  • pnpm: روابط صلبة + عزل صارم، يمنع "التبعيات الوهمية" (حزم غير مُعلن عنها لكنها متاحة)
  • cargo (Rust): على مستوى اللغة، كل حزمة تعتمد على نسخة واحدة فقط، متجنباً التعارضات تماماً
  • go mod (Go): استراتيجية اختيار النسخة الدنيا (MVS)، يختار أقل نسخة تُرضي جميع القيود

5. ملف القفل — حجر الزاوية للتعاون الجماعي

5.1 لماذا نحتاج ملف قفل؟

لنفترض أن package.json يقول "axios": "^1.6.0":

  • أنت تثبت اليوم ← تحصل على 1.6.8
  • زميلك يثبت غداً ← قد يحصل على 1.7.0 (نُشرت الليلة الماضية)
  • خادم CI الأسبوع القادم ← قد يحصل على 1.7.1

نفس الكود، ثلاثة نتائج مختلفة. ملف القفل يسجل النسخة الدقيقة لكل حزمة؛ الجميع يثبتون بناءً عليه والنتيجة متطابقة.

السيناريوالأمرالسلوك
مزامنة بيئة التطويرnpm installيراعي ملف القفل، لا يُرقّي النسخ
CI / نشر الإنتاجnpm ciيثبّت بصرامة حسب ملف القفل؛ إذا وُجد اختلاف يُبلغ عن خطأ
ترقية النسخ يدوياًnpm updateيُرقّي ضمن النطاق المسموح ويُحدّث ملف القفل

5.2 هل يجب رفع ملف القفل إلى Git؟

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

  • تطبيقات الويب، خدمات الخلفية: يجب رفعه لضمان تطابق التطوير والإنتاج
  • المكتبات المنشورة على npm: عادةً لا تُرفع؛ مستخدمو المكتبة لديهم ملفات قفل خاصة
  • مشاريع Python: requirements.txt يعمل كملف قفل في حد ذاته ويجب رفعه
  • مشاريع Go: go.sum يجب رفعه للتحقق من السلامة

6. البيئات الافتراضية في Python

Python لديها مفهوم يستحق اهتماماً خاصاً: البيئة الافتراضية (venv).

لماذا نحتاجها؟

Python يثبّت الحزم عاماً بشكل افتراضي. مشروعك أ يحتاج requests==2.28، ومشروعك ب يحتاج requests==2.31؛ كلاهما سيتعارض.

الحل: إنشاء بيئة افتراضية مستقلة لكل مشروع، دون تداخل.

bash
# 1. إنشاء بيئة افتراضية (نفّذ في جذر المشروع)
python -m venv .venv

# 2. تفعيل البيئة الافتراضية
source .venv/bin/activate        # macOS / Linux
.venv\Scripts\activate           # Windows (CMD)
.venv\Scripts\Activate.ps1       # Windows (PowerShell)

# 3. بعد التفعيل، pip install تؤثر فقط على البيئة الافتراضية الحالية
pip install requests

# 4. الخروج من البيئة الافتراضية
deactivate

⚠️ مشكلة شائعة على Windows: PowerShell يمنع تشغيل السكربتات افتراضياً؛ نفّذ أولاً:

powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

البدائل الحديثة:

  • conda create -n myproject python=3.11 — تدير حتى نسخة Python نفسها
  • uv venv && source .venv/bin/activate — مكتوبة بـ Rust، سرعة إنشاء فائقة

هل يجب رفع .venv إلى Git؟

لا! .venv يُنشأ محلياً ويجب إضافته إلى .gitignore. استخدم requirements.txt أو pyproject.toml لوصف التبعيات.


7. مرجع سريع للأسئلة الشائعة

س: هل يجب رفع node_modules إلى Git؟

لا! عادةً يزن مئات الميغابايت ويجب إضافته إلى .gitignore. مع package-lock.json يمكن لأي شخص إعادة البناء بسرعة عبر npm install.

س: ماذا أفعل عند فشل التثبيت / ظهور أخطاء غريبة؟

bash
# مسح ذاكرة التخزين المؤقت، حذف التثبيت القديم، إعادة المحاولة
npm cache clean --force
rm -rf node_modules package-lock.json   # macOS/Linux
rmdir /s /q node_modules && del package-lock.json  # Windows CMD
npm install

س: التثبيت بطيء جداً؟

bash
# التبديل لمرآة محلية (يُنصح بالكتابة في ملف .npmrc)
echo "registry=https://registry.npmmirror.com" > .npmrc

# pip يمكن أيضاً تهيئة مرآة
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple

س: ماذا أفعل إذا كانت الحزمة بها ثغرات أمنية؟

bash
npm audit          # فحص الثغرات المعروفة
npm audit fix      # إصلاح تلقائي للثغرات المتوافقة
npm audit fix --force  # ترقية إجبارية (قد تكون مدمرة، استخدم بحذر)

س: كيف أعرف أن حزمة ما موثوقة؟

على npmjs.com أو bundlephobia.com تحقق من:

  • التنزيلات الأسبوعية (كلما زادت، زادت الموثوقية)
  • آخر تحديث (أكثر من سنتين بدون تحديث، كن حذراً)
  • عدد التبعيات (كلما زادت، زاد احتمال إدخال مشاكل)
  • نجوم GitHub ونشاط المشكلات

س: أين تُثبّت برامج winget على Windows؟

winget يثبّت افتراضياً في دليل النظام (يحتاج مدير) أو %LOCALAPPDATA%\Microsoft\WindowsApps. Scoop يثبّت البرامج في %USERPROFILE%\scoop\apps\ بشكل موحد، مما يُسهّل الإدارة والنقل.


8. جدول مرجعي للمصطلحات

المصطلح بالإنجليزيةالترجمةالشرح
Packageحزمة / مكتبةوحدة كود كتبها آخرون ونشروها
Registryسجل / مستودعخادم تخزين مركزي لجميع الحزم (مثل npmjs.com)
Dependencyتبعيةحزم أخرى يحتاجها مشروعك للعمل
devDependencyتبعية تطويرحزم تحتاجها فقط في مرحلة التطوير (أطر الاختبار، أدوات البناء، إلخ)
Lockfileملف قفليسجل أرقام النسخ الدقيقة لضمان اتساق البيئة
SemVerالإصدار الدلالياتفاقية تسمية النسخ MAJOR.MINOR.PATCH
node_modulesدليل الوحداتالدليل الذي يخزن فيه npm الحزم المثبتة فعلياً
venvبيئة افتراضيةبيئة عزل حزم مستقلة لمشاريع Python
tarballملف مضغوطصيغة توزيع الحزم، عادةً ملف .tgz
Hoistingالرفعnpm يرفع التبعيات الفرعية للمستوى الأعلى لتجنب التثبيت المكرر
Phantom Dependencyتبعية وهميةحزم غير مُعلن عنها في ملف التهيئة لكنها قابلة للاستخدام (pnpm يمنعها)
npxمشغّل حزم مدمج في npm، يشغّل الحزم مؤقتاً دون تثبيتها
go.sumملف تحقق hash لوحدات Go، يمنع العبث بالتبعيات
Crateاسم وحدة "الحزمة" في نظام Rust البيئي
wingetمدير حزم Windows الرسمي (مدمج في Windows 10/11)

الخلاصة: جوهر مديري الحزم

تذكر الجوهر في أربع جمل:

  1. مدير الحزم = متجر تطبيقات: يساعدك في إيجاد وتثبيت وإدارة قطع الكود دون إعادة اختراع العجلة.
  2. ملف القفل = عقد الفريق: يُثبّت النسخ الدقيقة، ويجعل "يعمل على جهازي" شيئاً من الماضي.
  3. الإصدار الدلالي = لغة تواصل: ^ يحصل على التحديثات بأمان؛ عندما يتغير MAJOR، كن حذراً.
  4. محلي > عام: تبعيات المشروع تُثبّت محلياً قدر الإمكان؛ استخدم npx / uvx للأدوات المؤقتة للحفاظ على بيئة نظيفة.