إعداد Flutter والتطبيق الأول

pubspec.yaml وإدارة التبعيات

45 دقيقة الدرس 10 من 12

ما هو pubspec.yaml؟

ملف pubspec.yaml هو قلب كل مشروع Dart و Flutter. يحدد البيانات الوصفية لمشروعك والتبعيات والأصول والتكوين. يجب أن يحتوي كل مشروع Flutter على ملف pubspec.yaml في المجلد الجذري. فهم هذا الملف ضروري لإدارة مشروعك بفعالية.

ملاحظة: YAML (YAML Ain’t Markup Language) هو تنسيق بيانات قابل للقراءة يستخدم المسافة البادئة للهيكلة. يجب أن تستخدم المسافة البادئة في YAML مسافات وليس أبداً تبويبات. المسافة البادئة غير الصحيحة هي السبب الأكثر شيوعاً لأخطاء pubspec.yaml.

هيكل pubspec.yaml بالتفصيل

لنفحص كل قسم من ملف pubspec.yaml لمشروع Flutter نموذجي:

مثال كامل لـ pubspec.yaml

name: my_flutter_app
description: A personal profile card application built with Flutter.
publish_to: 'none'
version: 1.0.0+1

environment:
  sdk: '>=3.0.0 <4.0.0'

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.6
  http: ^1.1.0
  shared_preferences: ^2.2.2
  google_fonts: ^6.1.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.1

flutter:
  uses-material-design: true

  assets:
    - assets/images/
    - assets/data/config.json

  fonts:
    - family: Poppins
      fonts:
        - asset: assets/fonts/Poppins-Regular.ttf
        - asset: assets/fonts/Poppins-Bold.ttf
          weight: 700
        - asset: assets/fonts/Poppins-Italic.ttf
          style: italic

حقول البيانات الوصفية للمشروع

يحدد القسم العلوي هوية مشروعك:

  • name: اسم الحزمة (يجب أن يكون بأحرف صغيرة مع شرطات سفلية، بدون مسافات أو شرطات)
  • description: وصف موجز لمشروعك (مطلوب للنشر على pub.dev)
  • publish_to: 'none': يمنع النشر العرضي إلى pub.dev (استخدم للتطبيقات الخاصة)
  • version: إصدار دلالي بتنسيق major.minor.patch+build

تنسيق رقم الإصدار

# version: major.minor.patch+buildNumber
version: 1.0.0+1

# major: تغييرات جذرية (1.0.0 -> 2.0.0)
# minor: ميزات جديدة، متوافقة مع الخلف (1.0.0 -> 1.1.0)
# patch: إصلاحات أخطاء (1.0.0 -> 1.0.1)
# build: رقم البناء الداخلي لمتاجر التطبيقات (+1, +2, +3...)
#
# رقم البناء يُعيّن إلى:
# Android: versionCode في build.gradle
# iOS: CFBundleVersion في Info.plist

إضافة التبعيات من pub.dev

التبعيات هي حزم خارجية يستخدمها مشروعك. يستضيف سجل pub.dev آلاف الحزم لـ Flutter و Dart.

البحث عن الحزم وإضافتها

لإضافة حزمة، قم بزيارة pub.dev، ابحث عن الحزمة، وانسخ معلومات الإصدار إلى ملف pubspec.yaml الخاص بك.

إضافة التبعيات

dependencies:
  flutter:
    sdk: flutter

  # من pub.dev
  http: ^1.1.0              # عميل HTTP
  shared_preferences: ^2.2.2 # تخزين مفتاح-قيمة محلي
  provider: ^6.1.1           # إدارة الحالة
  google_fonts: ^6.1.0       # خطوط Google
  intl: ^0.19.0              # التدويل
  url_launcher: ^6.2.1       # فتح الروابط
  path_provider: ^2.1.1      # مسارات نظام الملفات
  cached_network_image: ^3.3.0  # تخزين الصور مؤقتاً
نصيحة: يمكنك أيضاً إضافة حزم باستخدام سطر الأوامر: flutter pub add http. هذا يضيف تلقائياً أحدث إصدار متوافق إلى pubspec.yaml ويشغّل flutter pub get.

قيود الإصدار

تحدد قيود الإصدار أي إصدارات الحزمة متوافقة مع مشروعك. فهم هذه القيود أمر بالغ الأهمية لتجنب تعارضات التبعيات.

صيغة قيود الإصدار

dependencies:
  # صيغة القبعة (موصى بها) - تسمح بتحديثات ثانوية وتصحيحية
  http: ^1.1.0          # تعني >=1.1.0 <2.0.0

  # إصدار محدد - هذا الإصدار المحدد فقط
  provider: 6.1.1       # الإصدار 6.1.1 فقط

  # صيغة النطاق - حدود صريحة
  intl: '>=0.18.0 <0.20.0'  # بين 0.18.0 و 0.20.0

  # أكبر من أو يساوي
  path: '>=1.8.0'      # 1.8.0 أو أعلى

  # أي إصدار (غير موصى به)
  yaml: any             # أي إصدار متاح

  # تبعية Git
  my_package:
    git:
      url: https://github.com/user/my_package.git
      ref: main          # فرع أو وسم أو تجزئة التزام

  # تبعية مسار (حزمة محلية)
  my_utils:
    path: ../my_utils    # مسار نسبي لحزمة محلية
تحذير: تجنب استخدام any لقيود الإصدار. يمكن أن يؤدي إلى تغييرات جذرية غير متوقعة عندما تصدر حزمة إصداراً رئيسياً جديداً. استخدم دائماً صيغة القبعة (^) لتحقيق توازن جيد بين الاستقرار والتحديثات.

dev_dependencies

تبعيات التطوير هي حزم مطلوبة فقط أثناء التطوير وليس في التطبيق النهائي. لا يتم تضمينها في بناء الإصدار.

dev_dependencies الشائعة

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.1       # قواعد الفحص
  build_runner: ^2.4.7         # توليد الكود
  json_serializable: ^6.7.1    # توليد تسلسل JSON
  mockito: ^5.4.3              # المحاكاة للاختبارات
  integration_test:
    sdk: flutter               # اختبار التكامل

تجاوزات التبعيات

أحياناً تتطلب حزمتان إصدارات مختلفة من نفس التبعية. يمكنك استخدام dependency_overrides لفرض إصدار محدد.

استخدام dependency_overrides

# استخدم بحذر! هذا يجبر جميع الحزم على استخدام
# الإصدار المحدد، مما قد يسبب أخطاء وقت التشغيل.
dependency_overrides:
  collection: 1.18.0
  meta: 1.11.0
تحذير: استخدم dependency_overrides فقط كملاذ أخير. فرض إصدارات غير متوافقة يمكن أن يسبب أخطاء وقت التشغيل يصعب تصحيحها. من الأفضل الانتظار حتى تحدّث الحزم تبعياتها.

أوامر flutter pub

يدير أمر flutter pub تبعيات مشروعك. إليك الأوامر الأساسية:

أوامر pub الأساسية

# تنزيل جميع التبعيات المدرجة في pubspec.yaml
flutter pub get

# ترقية التبعيات إلى أحدث الإصدارات المسموح بها
flutter pub upgrade

# التحقق من التبعيات القديمة
flutter pub outdated

# إضافة تبعية جديدة
flutter pub add http

# إضافة تبعية تطوير
flutter pub add --dev mockito

# إزالة تبعية
flutter pub remove http

# مسح ذاكرة التخزين المؤقت لـ pub
flutter pub cache clean

# إصلاح ذاكرة التخزين المؤقت لـ pub
flutter pub cache repair
ملاحظة: عند تشغيل flutter pub get، يُنشئ ملف pubspec.lock الذي يسجل الإصدارات الدقيقة المُحلّلة. يجب تسجيل هذا الملف في التحكم بالإصدارات للتطبيقات (لضمان بناءات متسقة) ولكن ليس للحزم.

إضافة الأصول

الأصول هي ملفات مُحزّمة مع تطبيقك، مثل الصور والخطوط وملفات JSON والموارد الأخرى. يجب التصريح عنها في pubspec.yaml.

إضافة الصور

تكوين أصول الصور

flutter:
  assets:
    # تضمين مجلد كامل
    - assets/images/

    # تضمين ملفات محددة
    - assets/images/logo.png
    - assets/images/background.jpg

    # تضمين المجلدات الفرعية (يجب إدراج كل منها بشكل منفصل)
    - assets/images/icons/
    - assets/images/avatars/

    # تضمين JSON أو ملفات بيانات أخرى
    - assets/data/config.json
    - assets/data/countries.json

استخدام أصول الصور في الكود

// التحميل من الأصول
Image.asset('assets/images/logo.png')

// بأبعاد محددة
Image.asset(
  'assets/images/profile.jpg',
  width: 120,
  height: 120,
  fit: BoxFit.cover,
)

// تحميل بيانات JSON من الأصول
Future<Map<String, dynamic>> loadConfig() async {
  final jsonString = await rootBundle.loadString(
    'assets/data/config.json',
  );
  return jsonDecode(jsonString);
}

أصول صور واعية بالدقة

يدعم Flutter دقات صور مختلفة لكثافات شاشة مختلفة. أنشئ مجلدات فرعية لكل دقة:

صور متعددة الدقة

# هيكل المجلد:
# assets/images/logo.png        (1x - الأساس)
# assets/images/2.0x/logo.png   (2x - كثافة عالية)
# assets/images/3.0x/logo.png   (3x - كثافة عالية جداً)

# في pubspec.yaml، صرّح فقط عن المجلد الأساسي:
flutter:
  assets:
    - assets/images/

# يختار Flutter تلقائياً الدقة الصحيحة
# بناءً على كثافة بكسل الجهاز

التصريح عن الخطوط

الخطوط المخصصة تمنح تطبيقك مظهراً فريداً. قم بتنزيل ملفات الخطوط (.ttf أو .otf) وصرّح عنها في pubspec.yaml.

التصريح عن الخطوط

flutter:
  fonts:
    - family: Poppins
      fonts:
        - asset: assets/fonts/Poppins-Regular.ttf
        - asset: assets/fonts/Poppins-Medium.ttf
          weight: 500
        - asset: assets/fonts/Poppins-Bold.ttf
          weight: 700
        - asset: assets/fonts/Poppins-Italic.ttf
          style: italic

    - family: RobotoMono
      fonts:
        - asset: assets/fonts/RobotoMono-Regular.ttf
        - asset: assets/fonts/RobotoMono-Bold.ttf
          weight: 700

استخدام الخطوط المخصصة في الكود

// الاستخدام في عنصر واجهة محدد
Text(
  'Hello World',
  style: TextStyle(
    fontFamily: 'Poppins',
    fontSize: 24,
    fontWeight: FontWeight.w700,
  ),
)

// تعيين كخط افتراضي للتطبيق بأكمله
MaterialApp(
  theme: ThemeData(
    fontFamily: 'Poppins',
    textTheme: const TextTheme(
      headlineLarge: TextStyle(fontWeight: FontWeight.w700),
      bodyMedium: TextStyle(fontWeight: FontWeight.w400),
    ),
  ),
)
نصيحة: بدلاً من تجميع ملفات الخطوط، فكر في استخدام حزمة google_fonts. تقوم بتنزيل الخطوط عند الطلب وتخزينها مؤقتاً، مما يقلل حجم حزمة تطبيقك الأولية: Text('Hello', style: GoogleFonts.poppins(fontSize: 24)).

قيود البيئة

يحدد قسم environment أي إصدارات Dart SDK متوافقة مع مشروعك:

تكوين البيئة

environment:
  # قيد Dart SDK
  sdk: '>=3.0.0 <4.0.0'

  # قيد Flutter SDK (اختياري، لكن موصى به)
  flutter: '>=3.10.0'

قيود النشر

إذا أردت يوماً نشر حزمتك على pub.dev، هناك حقول إضافية لتكوينها:

تكوين النشر

# للتطبيقات الخاصة (الأكثر شيوعاً لتطبيقات Flutter):
publish_to: 'none'

# للحزم العامة على pub.dev:
name: my_awesome_package
description: >
  وصف موجز لما تفعله حزمتك.
  يظهر هذا في نتائج البحث على pub.dev.
version: 1.0.0
homepage: https://github.com/username/my_awesome_package
repository: https://github.com/username/my_awesome_package
issue_tracker: https://github.com/username/my_awesome_package/issues

# مواضيع للتصنيف على pub.dev
topics:
  - flutter
  - widgets
  - ui

# المنصات التي تدعمها حزمتك
platforms:
  android:
  ios:
  web:
  windows:
  macos:
  linux:

الملخص

في هذا الدرس، تعلمت كل شيء عن pubspec.yaml وإدارة التبعيات:

  • هيكل وغرض كل قسم في pubspec.yaml
  • كيفية إضافة وتحديث وإزالة التبعيات من pub.dev
  • صيغة قيود الإصدار وأفضل الممارسات
  • الفرق بين dependencies و dev_dependencies
  • أوامر flutter pub الأساسية لإدارة الحزم
  • كيفية التصريح عن الأصول واستخدامها (صور، خطوط، ملفات بيانات)
  • قيود البيئة وتكوين النشر
ملاحظة: شغّل دائماً flutter pub get بعد تعديل pubspec.yaml. عادةً تقوم بيئة التطوير بهذا تلقائياً، ولكن إذا واجهت مشاكل، شغّله يدوياً من الطرفية.