متغيرات البيئة: ما هي، استخدامها وتكوينها في المشاريع المحمولة

المؤلف: IT Sectr نُشر: 2026-05-31 وقت القراءة: 8 دق

متغيرات البيئة هي قيم ديناميكية تُمرر إلى التطبيق عند بدء التشغيل لتكوين السلوك دون تغيير الكود. وهي تسمح بفصل تكوينات التطوير والاختبار والإنتاج. وفقًا لـ Twelve-Factor App، 2025، يجب تخزين التكوين في متغيرات البيئة، وليس في الكود. متغيرات البيئة تضمن إدارة آمنة لمفاتيح API وعنوان URL للخلفية وأعلام الميزات.

الخلاصة

  • متغيرات البيئة تفصل تكوين التطبيق عن الكود المصدري لبيئات تشغيل مختلفة
  • ملفات .env تخزن المتغيرات بتنسيق KEY=VALUE وتُستثنى من المستودع عبر .gitignore
  • iOS يستخدم xcconfig وإعدادات البناء لتمرير المتغيرات في مرحلة التجميع
  • Android يستخدم BuildConfig وgradle.properties لإنشاء حقول التكوين
  • الأمان: يجب تحميل المفاتيح والرموز عبر CI/CD، وليس تخزينها في الكود أو المستودع

ما هي متغيرات البيئة

متغيرات البيئة هي أزواج مفتاح-قيمة يمكن الوصول إليها من خلال عملية التطبيق عبر API نظام التشغيل. تُمرر إلى العملية عند إنشائها وتوجد فقط أثناء تشغيلها. على عكس معلمات التكوين المضمنة في الكود المصدري، لا تتطلب متغيرات البيئة إعادة تجميع لتغيير القيم. هذا مبدأ أساسي في Twelve-Factor App يضمن فصلاً واضحاً بين الكود والتكوين.

في تطوير التطبيقات المحمولة، تحل متغيرات البيئة مشكلة التكوينات المختلفة للبيئات: يستخدم المطور خادماً محلياً، ويستخدم المختبر بيئة staging، ويستخدم المستخدمون الإنتاج. بدلاً من تخزين ثلاثة عناوين URL للخلفية في الكود مع عبارات شرطية if-else، يمرر المطور عنوان URL واحداً عبر متغير بيئة في مرحلة البناء. هذا يبسط الكود ويزيل خطر استخدام خادم الإنتاج عن طريق الخطأ في بيئة اختبارية.

الميزة الرئيسية هي الأمان: البيانات الحساسة لا تصل إلى مستودع الكود. يتم تحميل مفاتيح API وأسرار Firebase ورموز الوصول إلى الخلفية والشهادات عبر CI/CD مباشرة إلى بيئة البناء. إذا حصل مهاجم على وصول إلى مستودع الكود، فلن يجد أسراراً هناك، لأنها مخزنة في مخازن محمية لنظام CI ويتم تمريرها فقط في مرحلة بناء الملف الثنائي.

لماذا نحتاج متغيرات البيئة في تطوير التطبيقات المحمولة

المشاريع المحمولة تحتوي على ثلاث بيئات على الأقل: التطوير والتجربة والإنتاج. كل بيئة تتطلب مجموعة خاصة من التكوينات: عنوان URL للخادم، اسم الحزمة، مخطط التوقيع وشهادات الإشعارات الفورية. بدون متغيرات البيئة، يضطر المطور إلى تغيير التكوين يدوياً قبل كل بناء، مما يؤدي إلى أخطاء: مفتاح إنتاج منسي في بناء اختباري قد يسبب إرسال إشعارات لمستخدمين حقيقيين أو استهلاك API مدفوع.

فصل البيئات

تسمح متغيرات البيئة بتبديل الخلفية دون تغيير الكود: فقط قم بتغيير القيمة في متغير API_BASE_URL. تُدار أعلام الميزات من خلال متغيرات مثل FEATURE_CHAT_ENABLED=true، مما يسمح بتمكين ميزات جديدة في staging دون التأثير على الإنتاج. لكل بيئة ملف .env خاص بها يتم تحميله في مرحلة البناء.

dart
class AppConfig {
  static final String apiBaseUrl =
    const String.fromEnvironment('API_BASE_URL',
      defaultValue: 'http://localhost:8080');
}

أمان المفاتيح

المفاتيح المبرمجة بشكل ثابت هي ثغرة شائعة في التطبيقات المحمولة. يقوم المهاجم بفك تجميع APK أو IPA باستخدام أدوات مثل jadx أو Hopper ويستخرج الأسرار من الملف الثنائي. حتى التعتيم لا يحمي النصوص الحرفية — فهي تُعثر عليها بسهولة في الكود بعد فك التجميع. تحل متغيرات البيئة هذه المشكلة بتمرير المفاتيح في مرحلة البناء عبر CI/CD، حيث يتم إخفاؤها في السجلات.

kotlin
object Config {
    val apiKey: String =
        System.getenv("API_KEY") ?: throw
            IllegalStateException("API_KEY not set")
}

تكامل CI/CD

تتكامل متغيرات البيئة مع خطوط أنابيب البناء: GitHub Actions وGitLab CI وBitrise وCircleCI تدعم المتغيرات السرية التي لا تظهر في السجلات. في مرحلة البناء، يستبدل CI القيم المناسبة حسب الفرع أو العلامة: لفرع develop يتم استخدام staging، لعلامة v* يتم استخدام الإنتاج. هذا يؤتمت العملية ويزيل العامل البشري، مما يضمن أن كل بناء يتلقى مجموعة التكوين الصحيحة.

ملفات .env ومكتبات الإدارة

ملف .env هو طريقة قياسية لتخزين متغيرات البيئة بتنسيق KEY=VALUE. لا يتم تضمينه في المستودع؛ بدلاً من ذلك، يُضاف .env.example مع قالب لجميع المتغيرات وقيم فارغة. كل مطور ينشئ ملف .env خاص به مع إعدادات محلية دون التأثير على تكوينات أعضاء الفريق الآخرين. تُستخدم ملفات منفصلة لبيئات مختلفة: .env.dev و.env.stage و.env.prod.

bash
# .env.example — قالب للمطورين
API_BASE_URL=http://localhost:8080
FEATURE_CHAT_ENABLED=true
SENTRY_DSN=

للمشاريع المحمولة، توجد مكتبات متخصصة للعمل مع ملفات .env:

  • flutter_dotenv (Flutter) — يحمل المتغيرات من .env في وقت التشغيل عبر dotenv.load()
  • BuildConfig (Android) — يُنشئ حقولاً منمطة من قيم build.gradle
  • xcconfig (iOS) — يربط ملفات التكوين بمخططات بناء Xcode المختلفة
  • react-native-config (React Native) — إدارة المتغيرات عبر ملفات .env

إعدادات التفرع في CI/CD تسمح باستبدال ملفات .env مختلفة: .env.dev للخوادم الاختبارية، .env.stage للإصدار المسبق و.env.prod للنشر في متاجر التطبيقات. تُحمّل الملفات التي تحتوي على أسرار من مخزن آمن (Vault، AWS Secrets Manager) ولا تُخزّن في المستودع. هذا يضمن أنه حتى في حالة اختراق نظام التحكم في الإصدارات، تبقى الأسرار محمية.

متغيرات البيئة في مشاريع iOS

يستخدم نظام iOS البيئي ملفات xcconfig لإدارة المتغيرات على مستوى البناء. تُرفع هذه الملفات إلى مخططات Xcode وتسمح بتجاوز القيم لتكوينات Debug وRelease. تدعم ملفات xcconfig الوراثة: يمكن إنشاء ملف أساسي بإعدادات مشتركة وملفات محددة لكل بيئة.

تكوين ملفات xcconfig

ملفات xcconfig تخزن المتغيرات بتنسيق KEY = VALUE وتُرفق بمخطط البناء في Xcode من خلال إعدادات Configuration. المتغيرات من xcconfig متاحة في Info.plist عبر الصيغة $(NOMBRE_VARIABLE)، مما يسمح بمعرفات حزمة وأسماء تطبيقات مختلفة لمخططات مختلفة. للتحديد السريع للبيئة، يُضاف اللاحقة Dev أو Staging إلى اسم التطبيق.

bash
# Config/Dev.xcconfig — تكوين التطوير
API_BASE_URL = http://localhost:3000
BUNDLE_ID_SUFFIX = .dev
APP_DISPLAY_NAME = MyApp Dev

كود Swift لقراءة المتغيرات

للوصول في وقت التشغيل إلى المتغيرات في iOS، يُستخدم ملف Configuration.swift الذي يقرأ القيم من Info.plist عبر Bundle.main.object(forInfoDictionaryKey:). هذا النهج يضمن أن المتغيرات تُحدد في مرحلة البناء وتكون متاحة للتطبيق فور بدء التشغيل. تُقرأ القيم مرة واحدة أثناء تهيئة الوحدة وتُخزّن مؤقتاً للوصول السريع طوال دورة حياة التطبيق.

swift
enum AppEnvironment {
    static var apiBaseURL: URL {
        guard let urlString = Bundle.main
            .object(forInfoDictionaryKey: "API_BASE_URL"),
              let url = URL(string: urlString as! String)
        else { fatalError("API_BASE_URL is not configured") }
        return url
    }

    static var isChatEnabled: Bool {
        Bundle.main.object(
            forInfoDictionaryKey: "FEATURE_CHAT_ENABLED"
        ) as? Bool ?? false
    }
}

متغيرات البيئة في مشاريع Android

يدعم Android متغيرات البيئة عبر BuildConfig — فئة تُنشأ تلقائياً تُحدد حقولها في ملف build.gradle للوحدة. يُنشأ BuildConfig في مرحلة التجميع لكل flavor ونوع بناء على حدة. هذا يسمح بقيم مختلفة للتصحيح والإصدار دون استخدام عوامل شرطية في الكود، مما يحسن الأداء والأمان.

تكوين حقول BuildConfig

تُحدد حقول BuildConfig عبر buildConfigField في defaultConfig أو في buildTypes محددة. يُنشأ buildType أو productFlavor منفصل لكل بيئة. هذا يضمن عزلاً صارماً للتكوينات: التصحيح يستخدم خادماً محلياً، الإصدار يستخدم الإنتاج. حقول BuildConfig منمطة بشكل ثابت، مما يزيل الأخطاء عند الوصول إليها في الكود.

groovy
// build.gradle (Module: app)
android {
    defaultConfig {
        buildConfigField "String", "API_BASE_URL",
            "\"http://localhost:8080\""
    }
    buildTypes {
        debug {
            buildConfigField "String", "API_BASE_URL",
                "\"http://dev.api.itsectr.com\""
        }
        release {
            buildConfigField "String", "API_BASE_URL",
                "\"https://api.itsectr.com\""
        }
    }
}

gradle.properties للقيم المشتركة

ملف gradle.properties في جذر المشروع يخزن متغيرات Gradle العامة. وهي متاحة في جميع الوحدات عبر الصيغة $variableName وتُستخدم لتحديد إصدارات التبعيات وأعلام البناء ومفاتيح API. على عكس BuildConfig، يعمل gradle.properties فقط في مرحلة تكوين Gradle، وليس في وقت تشغيل التطبيق. لذلك، كلمات المرور ومفاتيح API المحددة في gradle.properties غير مرئية في الكود المفكك، لأنها تُستخدم فقط لإنشاء BuildConfig في مرحلة التجميع.

groovy
# gradle.properties
SENTRY_DSN=https://key@sentry.io/project
MAPS_API_KEY=AIzaSy...

للنقل الآمن للأسرار في مشاريع Android، يُوصى باستخدام local.properties (مستبعد من VCS) أو تحميل القيم من متغيرات CI/CD في build.gradle عبر System.getenv(). هذا يضمن أن المفاتيح لا تصل إلى المستودع. عند النشر في Google Play Console، تأكد من استبدال جميع مفاتيح التصحيح بإصدارات الإنتاج عبر buildTypes أو productFlavors مختلفة مع قيم BuildConfig المقابلة.

الأسئلة الشائعة

هل يمكن استخدام متغيرات البيئة في Flutter؟

نعم، يدعم Flutter متغيرات البيئة من خلال حزمة flutter_dotenv للوصول في وقت التشغيل أو عبر القنوات الأصلية للمتغيرات المنصية. يتوفر أيضاً مُنشئ String.fromEnvironment في Dart لتمرير القيم في مرحلة التجميع عبر --dart-define، وهي الطريقة المفضلة لمشاريع Flutter.

ما الفرق بين BuildConfig وgradle.properties؟

BuildConfig هو فئة Java ذات حقول منمطة تُنشأ في مرحلة التجميع لكل buildType وflavor. gradle.properties هو ملف نصي بأزواج مفتاح-قيمة متاح لجميع وحدات Gradle في مرحلة تكوين البناء. BuildConfig يعمل في وقت تشغيل التطبيق، gradle.properties — فقط في سكريبتات Gradle.

كيف نمنع تسرب ملف .env إلى المستودع؟

أضف .env إلى ملف .gitignore لمستودعك. في المستودع، أضف فقط .env.example بقيم فارغة ووصف لكل متغير. لـ CI/CD، استخدم الأسرار المشفرة في إعدادات GitHub Actions أو GitLab CI أو Bitrise، والتي تُخفى في السجلات وغير متاحة للقراءة بعد اكتمال البناء.

كيف نمرر متغيرات البيئة عبر CI/CD؟

معظم أنظمة CI تدعم متغيرات البيئة السرية. في GitHub Actions هي Secrets، في GitLab CI — CI/CD Variables، في Bitrise — Secrets. في مرحلة البناء، تُمرر إلى سكريبت البناء عبر process.env أو System.getenv(). المتغيرات السرية لا تظهر في سجلات البناء وغير متاحة في forks المستودع.

ما هي أعلام الميزات عبر متغيرات البيئة؟

أعلام الميزات هي متغيرات منطقية تتحكم في تمكين أو تعطيل الوظائف دون إعادة ترجمة الكود. مثال: FEATURE_NEW_PAYMENT=true يمكّن نظام دفع جديد في staging للاختبار. في الإنتاج، نفس العلم مضبوط على false حتى يتم نشر الخلفية بالكامل. هذا يسمح بتنفيذ التغييرات بشكل تدريجي آمن وتراجعها إذا ظهرت مشاكل.

الملخص

  • متغيرات البيئة تفصل التكوين عن الكود المصدري لبيئات تطوير مختلفة
  • ملفات .env مع قالب .env.example — المعيار لإدارة المتغيرات في الفرق مع فصل البيئات
  • iOS xcconfig يربط ملفات التكوين بمخططات Xcode مع دعم الوراثة وتكامل Info.plist
  • Android BuildConfig يُنشئ حقولاً منمطة من build.gradle لكل buildType على حدة
  • أسرار CI/CD تنقل البيانات الحساسة في مرحلة البناء دون تخزينها في المستودع
  • أعلام الميزات عبر المتغيرات تسمح بتمكين الوظائف في بيئة محددة دون إعادة ترجمة
  • الأمان: المفاتيح مشفرة في CI ولا تصل إلى الملف الثنائي القابل لفك التجميع للتطبيق

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا