Dart: إدارة حزم Dart — نظام pub البيئي والتبعية
آخر تحديث: 2026-08-26
إدارة التبعيات هي سلسلة توريد المشروع — فقط من خلال إدارة التبعيات بشكل جيد يمكن أن يكون المشروع مستقراً.
1. ما ستتعلمه
- تكوين pubspec.yaml الكامل: dependencies / dev_dependencies / dependency_overrides
- صياغة قيد الإصدار: ^ / >= / any والإصدار الدلالي
- البحث عن الحزم وتقييمها واختيارها على pub.dev
- استضافة الحزم الخاصة وتبعيات git
- سيناريو بوب: تكوين تبعية خط أنابيب البيانات
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، مما يضمن التوافق.
dependencies:
http: ^1.2.0 # متوافق مع 1.x، تحديثات طفيفة/إصلاحات آمنة
args: ^2.4.2 # متوافق مع 2.x
csv: ^6.0.0 # متوافق مع 6.x
(3) الفوائد
- تجعل قيود الإصدار ترقيات التبعيات آمنة وقابلة للتحكم.
- يساعد نظام تقييم نقاط pub في pub.dev على اختيار حزم عالية الجودة.
- يحل
dependency_overridesتعارضات الإصدار مؤقتاً.
3. تكوين pubspec.yaml الكامل
(1) بنية التكوين
▶ مثال
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.
: pubspec.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) الإصدار الدلالي
▶ مثال
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.
: صياغة قيد الإصدار
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 |
▶ مثال
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.
: تعارض الإصدار والحل
# السيناريو: 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 موثق | الناشر موثق | عالٍ |
| التحديثات الحديثة | نشاط الصيانة | عالٍ |
| المنصة | المنصات المدعومة | حسب الحاجة |
▶ مثال
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.
: اختيار حزم خط أنابيب البيانات
# معايير اختيار حزم خط أنابيب البيانات:
#
# 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
▶ مثال
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.
: تبعيات Git
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
▶ مثال
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.
: تبعيات المسار المحلي
# للتطوير والاختبار المحلي
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. سيناريو بوب: تكوين تبعية خط أنابيب البيانات
▶ مثال
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.
: تبعيات المشروع الكاملة
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. المثال الكامل: إدارة تبعية خط أنابيب البيانات
// ============================================
// عرض إدارة تبعية خط أنابيب البيانات
// يوضح كيفية استخدام التبعيات الرئيسية
// ============================================
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);
}
> **الإخراج:** شغّل في DartPad محلي أو عبر `dart run`. جميع الأمثلة في دورة Dart هذه مبنية على Dart 3.x / Flutter 3.x. قد تختلف النتائج قليلاً حسب إصدار SDK.
الإخراج (
dart run bin/main.dart -i orders.csv -o report.json -V):
=== 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.
📖 ملخص
- pubspec.yaml هو مركز تكوين المشروع: يدير التبعيات والإصدارات والبيانات الوصفية.
- استخدام صياغة
^لقيود الإصدار هو الأكثر أماناً، مما يسمح بالترقيات التلقائية داخل إصدار رئيسي. - يساعد نظام تقييم نقاط pub في pub.dev على اختيار حزم عالية الجودة.
- تبعيات Git مخصصة للحزم غير المنشورة/الخاصة، بينما تبعيات المسار للتطوير المحلي.
dependenciesمقابلdev_dependenciesيفصل بين تبعيات وقت التشغيل ووقت التطوير.
📝 تمارين
- أساسي (صعوبة ⭐): أنشئ مشروعاً باستخدام
dart create، أضف تبعياتargsوpath، شغّلdart pub get، وافحص محتوى ملف pubspec.lock. - متوسط (صعوبة ⭐⭐): ابحث عن حزمة
httpعلى pub.dev، سجّل نقاط pub والإعجابات وآخر إصدار والمنصات المدعومة. اكتب تقرير تقييم اختيار الحزمة. - تحدي (صعوبة ⭐⭐⭐): أنشئ ملف pubspec.yaml يتضمن تبعية git وتبعية مسار، محاكياً سيناريو تطوير monorepo. استخدم
dependency_overridesلحل تعارض إصدار افتراضي.