Dart: إدارة حزم Dart — نظام pub البيئي والتبعية

آخر تحديث: 2026-08-26

إدارة التبعيات هي سلسلة توريد المشروع — فقط من خلال إدارة التبعيات بشكل جيد يمكن أن يكون المشروع مستقراً.

1. ما ستتعلمه


2. قصة مطور حقيقية

(1) نقطة الألم: فشل البناء بسبب تعارض إصدار التبعية

استخدم فريق أليس http: ^1.1.0 في مشروع خط أنابيب البيانات الخاص بهم، لكن تبعية أخرى، api_client، تطلبت http: >=0.13.0 <1.0.0. كانت قيود الإصدار غير متوافقة، مما تسبب في فشل dart pub get. والأسوأ من ذلك، أن تبعية ما قامت بصمت بتحديث إصدار فرعي، مما أدخل تغييراً جذرياً تسبب في فشل بناء CI. استغرق الفريق يومين في التحقيق.

(2) الحل: الإصدار الدلالي

تستخدم Dart الإصدار الدلالي (SemVer) وصياغة قيد الإصدار لجعل إدارة التبعيات قابلة للتنبؤ. ^1.2.0 تعني >=1.2.0 <2.0.0، مما يضمن التوافق.

YAML
dependencies:
  http: ^1.2.0       # متوافق مع 1.x، تحديثات طفيفة/إصلاحات آمنة
  args: ^2.4.2        # متوافق مع 2.x
  csv: ^6.0.0         # متوافق مع 6.x

(3) الفوائد


3. تكوين pubspec.yaml الكامل

(1) بنية التكوين

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.

: pubspec.yaml الكامل

YAML
name: datapipeline
description: A CLI tool for e-commerce data analytics processing million-level orders
version: 1.0.0
homepage: https://github.com/bob/datapipeline
repository: https://github.com/bob/datapipeline
documentation: https://datapipeline.dev/docs

environment:
  sdk: ^3.0.0

dependencies:
  # تحليل وسائط CLI
  args: ^2.4.2
  # عميل HTTP لاستدعاءات API
  http: ^1.2.0
  # تحليل ملف CSV
  csv: ^6.0.0
  # دعم قاعدة بيانات SQLite
  sqlite3: ^2.4.0
  # أدوات معالجة المسار
  path: ^1.9.0
  # إطار تسجيل
  logging: ^1.2.0
  # تحليل تكوين YAML
  yaml: ^3.1.2

dev_dependencies:
  # إطار الاختبار
  test: ^1.24.0
  # مشغل توليد الكود
  build_runner: ^2.4.0
  # تسلسل JSON
  json_serializable: ^6.7.0
  # قواعد الفحص
  lints: ^3.0.0

dependency_overrides:
  # مؤقت: حل تعارض الإصدار
  # transitive: ^1.0.0

executables:
  datapipeline: datapipeline
الحقل مطلوب الوصف
name نعم اسم الحزمة (أحرف صغيرة + شرطات سفلية)
description نعم وصف الحزمة (60-180 حرفاً)
version لا رقم الإصدار الدلالي
environment نعم قيود إصدار SDK
dependencies لا تبعيات وقت التشغيل
dev_dependencies لا تبعيات وقت التطوير
dependency_overrides لا فرض إصدار محدد

4. صياغة قيد الإصدار

(1) الإصدار الدلالي

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.

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

YAML
dependencies:
  # صياغة علامة الإقحام: ^1.2.3 = >=1.2.3 <2.0.0
  package_a: ^1.2.3

  # صياغة النطاق
  package_b: ">=1.2.3 <2.0.0"

  # الحد الأدنى للإصدار
  package_c: ">=1.2.3"

  # أي إصدار (خطير!)
  package_d: any

  # إصدار دقيق
  package_e: "1.2.3"

  # تبعية Git
  package_f:
    git:
      url: https://github.com/user/package_f.git
      ref: main

  # تبعية المسار (التطوير المحلي)
  package_g:
    path: ../package_g
الصياغة المعنى المثال الأمان
^1.2.3 >=1.2.3 <2.0.0 الأكثر شيوعاً عالٍ
>=1.2.3 <2.0.0 قيد النطاق تحكم دقيق عالٍ
>=1.2.3 الحد الأدنى للإصدار مخاطرة أعلى متوسط
any أي إصدار غير موصى به منخفض
1.2.3 إصدار دقيق مثبت عالٍ (غير مرن)

(2) قواعد حل الإصدار

قاعدة SemVer الوصف المثال
الإصدار الرئيسي تغييرات API غير متوافقة 1.x ← 2.x
الإصدار الفرعي ميزات جديدة متوافقة مع الإصدارات السابقة 1.2 ← 1.3
إصدار الإصلاح إصلاحات أخطاء متوافقة مع الإصدارات السابقة 1.2.3 ← 1.2.4

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.

: تعارض الإصدار والحل

YAML
# السيناريو: package_a يتطلب http ^0.13.0، package_b يتطلب http ^1.0.0
# هذا تعارض إصدار رئيسي - غير متوافق!

# الحل 1: تحديث package_a إلى إصدار يدعم http ^1.0.0
# الحل 2: استخدام dependency_overrides (ملاذ أخير)
dependencies:
  http: ^1.2.0

dependency_overrides:
  http: ^1.2.0  # فرض إصدار محدد

5. تقييم الحزم على pub.dev

(1) معايير التقييم

البُعد المقياس الوزن
نقاط Pub دعم المنصة/التوثيق/صحة التبعيات عالٍ
الإعجابات الاعتراف المجتمعي متوسط
الشعبية عدد الاستخدامات متوسط
Pub موثق الناشر موثق عالٍ
التحديثات الحديثة نشاط الصيانة عالٍ
المنصة المنصات المدعومة حسب الحاجة

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.

: اختيار حزم خط أنابيب البيانات

YAML
# معايير اختيار حزم خط أنابيب البيانات:
#
# args (نقاط pub: 140/140، إعجابات: 300+)
#   - حزمة فريق Dart الرسمية
#   - API مستقر، موثق جيداً
#   - مثالي لتحليل وسائط CLI
#
# http (نقاط pub: 140/140، إعجابات: 1000+)
#   - حزمة فريق Dart الرسمية
#   - عميل HTTP قياسي
#   - يدعم المعترضات والبث
#
# csv (نقاط pub: 130/140، إعجابات: 100+)
#   - حزمة مجتمعية
#   - يتعامل مع تحليل/كتابة CSV
#   - صيانة نشطة
#
# json_serializable (نقاط pub: 140/140، إعجابات: 500+)
#   - حزمة Google
#   - توليد كود لـ JSON
#   - آمن النوع، متوافق مع AOT

6. الحزم الخاصة وتبعيات Git

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.

: تبعيات Git

YAML
dependencies:
  # مستودع git عام
  custom_client:
    git:
      url: https://github.com/bob/custom_client.git
      ref: v1.0.0  # علامة أو فرع أو commit

  # مستودع git خاص (SSH)
  internal_sdk:
    git:
      url: git@github.com:bob/internal_sdk.git
      ref: main

  # مسار محدد داخل مستودع git
  shared_utils:
    git:
      url: https://github.com/bob/monorepo.git
      path: packages/shared_utils
      ref: stable

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.

: تبعيات المسار المحلي

YAML
# للتطوير والاختبار المحلي
dependencies:
  core_lib:
    path: ../core_lib

  shared_models:
    path: ./packages/shared_models
مصدر التبعية الصياغة السيناريو المعمول به
pub.dev package: ^1.0.0 التبعيات الرسمية (موصى به)
Git git: url: ... حزم غير منشورة/خاصة
مسار محلي path: ../local التطوير/التصحيح، monorepo

7. سيناريو بوب: تكوين تبعية خط أنابيب البيانات

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.

: تبعيات المشروع الكاملة

YAML
name: datapipeline
description: E-commerce analytics CLI tool for processing million-level orders
version: 1.0.0

environment:
  sdk: ^3.0.0

dependencies:
  # إطار CLI
  args: ^2.4.2
  # تنسيق إخراج وحدة التحكم
  cli_util: ^0.4.1
  # عميل HTTP
  http: ^1.2.0
  # تحليل CSV
  csv: ^6.0.0
  # تسلسل JSON
  json_annotation: ^4.8.0
  # أدوات المسار
  path: ^1.9.0
  # التسجيل
  logging: ^1.2.0
  # تكوين YAML
  yaml: ^3.1.2

dev_dependencies:
  # الاختبار
  test: ^1.24.0
  # المحاكاة
  mockito: ^5.4.0
  # توليد الكود
  build_runner: ^2.4.0
  json_serializable: ^6.7.0
  # الفحص
  lints: ^3.0.0
  # التغطية
  coverage: ^1.6.0

8. المثال الكامل: إدارة تبعية خط أنابيب البيانات

DART
// ============================================
// عرض إدارة تبعية خط أنابيب البيانات
// يوضح كيفية استخدام التبعيات الرئيسية
// ============================================

import 'package:args/args.dart';
import 'package:path/path.dart' as p;

const String version = '1.0.0';

class DataPipelineCli {
  final ArgParser parser;

  DataPipelineCli()
      : parser = ArgParser()
          ..addFlag('version', abbr: 'v', negatable: false, help: 'Show version')
          ..addFlag('help', abbr: 'h', negatable: false, help: 'Show help')
          ..addOption('input', abbr: 'i', help: 'Input data source')
          ..addOption('output', abbr: 'o', defaultsTo: 'report.json', help: 'Output path')
          ..addOption('format', allowed: ['json', 'csv', 'html'], defaultsTo: 'json')
          ..addFlag('verbose', abbr: 'V', help: 'Verbose logging')
          ..addOption('batch-size', defaultsTo: '10000', help: 'Records per batch');

  Future<void> run(List<String> arguments) async {
    try {
      final results = parser.parse(arguments);

      if (results['help'] as bool) {
        _printHelp();
        return;
      }

      if (results['version'] as bool) {
        print('DataPipeline v$version');
        return;
      }

      final input = results['input'] as String?;
      final output = results['output'] as String;
      final format = results['format'] as String;
      final verbose = results['verbose'] as bool;
      final batchSize = int.parse(results['batch-size'] as String);

      if (input == null) {
        print('Error: --input is required');
        _printHelp();
        return;
      }

      // استخدام حزمة path للمسارات متعددة المنصات
      final inputPath = p.normalize(input);
      final outputPath = p.normalize(output);
      final ext = p.extension(inputPath);

      print('=== DataPipeline v$version ===');
      if (verbose) {
        print('Input:      $inputPath (${ext.isEmpty ? "unknown" : ext})');
        print('Output:     $outputPath');
        print('Format:     $format');
        print('Batch size: $batchSize records');
        print('SDK:        ${_getSdkInfo()}');
      }

      print('Processing: $inputPath → $outputPath ($format)');
    } on FormatException catch (e) {
      print('Argument error: ${e.message}');
      print(parser.usage);
    }
  }

  void _printHelp() {
    print('DataPipeline - E-commerce analytics CLI tool');
    print('');
    print('Usage: datapipeline [options]');
    print(parser.usage);
  }

  String _getSdkInfo() {
    // في مشروع حقيقي، استخدم dart:io Platform
    return 'Dart 3.x';
  }
}

void main(List<String> arguments) async {
  final cli = DataPipelineCli();
  await cli.run(arguments);
}
TEXT 📖 للعرض فقط
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.

الإخراج (dart run bin/main.dart -i orders.csv -o report.json -V):

TEXT 📖 للعرض فقط
=== DataPipeline v1.0.0 ===
Input:      orders.csv (.csv)
Output:     report.json
Format:     json
Batch size: 10000 records
SDK:        Dart 3.x
Processing: orders.csv → report.json (json)

❓ أسئلة شائعة

س: ما الفرق بين dependencies و dev_dependencies؟ ج: dependencies هي الحزم المطلوبة في وقت التشغيل؛ dev_dependencies مطلوبة فقط أثناء التطوير (الاختبار، توليد الكود، الفحص). عند نشر حزمة، لا يتم تمرير dev_dependencies إلى المستخدمين.

س: ما الفرق بين ^ و >=؟ ج: ^1.2.0 يكافئ >=1.2.0 <2.0.0، مما يحد من التحديثات داخل إصدار رئيسي. >=1.2.0 ليس له حد أعلى. ^ أكثر أماناً وموصى به.

س: ما الفرق بين dart pub upgrade و dart pub get؟ ج: dart pub get يجلب التبعيات ضمن قيود pubspec.yaml. يحاول dart pub upgrade الترقية إلى أحدث الإصدارات ضمن تلك القيود.

س: هل يجب رفع pubspec.lock إلى التحكم في الإصدارات؟ ج: لمشاريع التطبيقات (CLI، Flutter App)، نعم، لضمان استخدام الفريق لإصدارات متطابقة. لمشاريع المكتبات (الحزم)، لا، للسماح للمستخدمين بالحصول على أحدث إصدار متوافق.

س: كيف أختار حزمة على pub.dev؟ ج: تحقق من نقاط pub (≥130 جيد)، والإعجابات، ووقت التحديث الحديث، وما إذا كان الناشر موثقاً. فضل الحزم الرسمية من Dart/Google.

س: متى أستخدم dependency_overrides؟ ج: فقط مؤقتاً عندما لا يمكن حل التعارضات من خلال قيود الإصدار العادية. الاستخدام طويل الأمد يخفي المشاكل الكامنة. أزله بمجرد حل المشكلة.

س: هل تبعيات git آمنة للإنتاج؟ ج: غير موصى به. تبعيات git ليس لديها ضمان إصدار، ويمكن دفع ref بالقوة. للإصدارات الرسمية، استخدم حزم مُصدَرة الإصدار من pub.dev.


📖 ملخص


📝 تمارين

  1. أساسي (صعوبة ⭐): أنشئ مشروعاً باستخدام dart create، أضف تبعيات args و path، شغّل dart pub get، وافحص محتوى ملف pubspec.lock.
  2. متوسط (صعوبة ⭐⭐): ابحث عن حزمة http على pub.dev، سجّل نقاط pub والإعجابات وآخر إصدار والمنصات المدعومة. اكتب تقرير تقييم اختيار الحزمة.
  3. تحدي (صعوبة ⭐⭐⭐): أنشئ ملف pubspec.yaml يتضمن تبعية git وتبعية مسار، محاكياً سيناريو تطوير monorepo. استخدم dependency_overrides لحل تعارض إصدار افتراضي.

← الدرس السابق | الدرس التالي →

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%