Flutter मोबाइल विकास · पाठ

बिल्ड फ़्लेवर और पर्यावरण कॉन्फ़िगरेशन

प्रत्येक पर्यावरण की एसेट और Dart-define कॉन्फ़िगरेशन के साथ dev, staging और prod फ़्लेवर परिभाषित कीजिए।

पाठ 1, कुल 4 में से13 चरण

बिल्ड फ़्लेवर और पर्यावरण कॉन्फ़िगरेशन, CoddyKit पर Flutter मोबाइल विकास का एक निःशुल्क पाठ है। यह 4 में से 1वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह Flutter मोबाइल विकास सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। Flutter मोबाइल विकास पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

बिल्ड फ़्लेवर क्यों महत्वपूर्ण हैं

प्रोडक्शन Flutter ऐप शायद ही कभी केवल एक बैकएंड से जुड़ता है। आपको स्थानीय या स्टेजिंग API की ओर संकेत करने वाला डेव बिल्ड, QA के लिए स्टेजिंग बिल्ड और स्टोर के लिए सुरक्षित प्रोड बिल्ड चाहिए।

  • फ़्लेवर नामित बिल्ड रूपांतर होते हैं, जिनमें ऐप आईडी, आइकन, नाम और साइनिंग अलग हो सकते हैं।
  • एनवायरनमेंट कॉन्फ़िगरेशन वह डेटा है, जिसे प्रत्येक फ़्लेवर शामिल करता है: आधार URL, फ़ीचर फ़्लैग और API कुंजी।

लक्ष्य यह है कि डेव, स्टेजिंग और प्रोड को एक ही डिवाइस पर साथ-साथ इंस्टॉल किया जा सके और प्रत्येक पूरी तरह अलग हो, ताकि भ्रम की कोई संभावना न रहे।

दो परतें: मूल फ़्लेवर और Dart-Define

एक सुव्यवस्थित सेटअप दो अलग चिंताओं को अलग रखता है:

  • मूल फ़्लेवर (Android productFlavors, iOS schemes/xcconfig) ऐप की पहचान नियंत्रित करते हैं: बंडल आईडी, प्रदर्शित नाम और आइकन।
  • Dart-define मान रनटाइम कॉन्फ़िगरेशन नियंत्रित करते हैं, जिसे आपका Dart कोड पढ़ता है: API URL, एनवायरनमेंट नाम और लॉग स्तर।

मूल फ़्लेवर डेव, स्टेजिंग और प्रोड को com.acme.app.dev जैसी अलग आईडी के साथ डिवाइस पर साथ रहने देते हैं। Dart-define सीक्रेट और URL को स्रोत नियंत्रण से बाहर रखता है और कंपाइलेशन के समय संस्करण में स्थिर कर देता है।

टाइप-सुरक्षित एनवायरनमेंट Enum परिभाषित करना

Dart में शुरुआत इस बात के लिए एकल सत्य-स्रोत से करें कि कौन-कौन से एनवायरनमेंट मौजूद हैं। Enum टाइपिंग की गलतियों को रोकता है और सभी संभावित switch स्थितियों को संभालने देता है।

यह स्निपेट बिना किसी Flutter निर्भरता के साधारण Dart है, इसलिए यह कहीं भी चल सकता है।

enum Environment { dev, staging, prod }

String labelFor(Environment env) {
  switch (env) {
    case Environment.dev:
      return 'Development';
    case Environment.staging:
      return 'Staging';
    case Environment.prod:
      return 'Production';
  }
}

void main() {
  for (final env in Environment.values) {
    print('${env.name} -> ${labelFor(env)}');
  }
}

कंपाइल समय पर Dart-Define पढ़ना

Flutter String.fromEnvironment, bool.fromEnvironment और int.fromEnvironment के माध्यम से कंपाइल-समय के स्थिरांक उपलब्ध कराता है। बिल्ड के समय इन्हें --dart-define के साथ पास किया जाता है।

  • मान बाइनरी में शामिल कर दिए जाते हैं; उन्हें डिवाइस से रनटाइम पर नहीं पढ़ा जाता।
  • हमेशा defaultValue दें, ताकि कोई परिभाषा छूटने पर परिणाम अनुमानित रहे।

क्योंकि ये const हैं, इसलिए इनका मूल्यांकन const संदर्भों में भी किया जा सकता है।

const String apiUrl = String.fromEnvironment(
  'API_URL',
  defaultValue: 'http://localhost:8080',
);

const String envName = String.fromEnvironment(
  'ENV',
  defaultValue: 'dev',
);

const bool analyticsEnabled = bool.fromEnvironment(
  'ANALYTICS',
  defaultValue: false,
);

void main() {
  print('env=$envName url=$apiUrl analytics=$analyticsEnabled');
}

AppConfig ऑब्जेक्ट बनाना

यदि आप पूरे कोडबेस में String.fromEnvironment कॉल बिखेर देंगे, तो नियंत्रण खो देंगे। इन्हें एक अपरिवर्तनीय AppConfig में केंद्रीकृत करें, जिसे एक बार निर्धारित करके आगे पास करें।

इससे प्रत्येक फ़्लेवर का अंतर एक ही जाँच योग्य स्थान पर रहता है और परीक्षण बहुत सरल हो जाता है: बस अपने इच्छित मानों के साथ एक AppConfig बनाएँ।

class AppConfig {
  final String envName;
  final String apiUrl;
  final bool analyticsEnabled;

  const AppConfig({
    required this.envName,
    required this.apiUrl,
    required this.analyticsEnabled,
  });

  factory AppConfig.fromEnvironment() {
    return const AppConfig(
      envName: String.fromEnvironment('ENV', defaultValue: 'dev'),
      apiUrl: String.fromEnvironment('API_URL',
          defaultValue: 'http://localhost:8080'),
      analyticsEnabled:
          bool.fromEnvironment('ANALYTICS', defaultValue: false),
    );
  }

  bool get isProd => envName == 'prod';
}

void main() {
  final config = AppConfig.fromEnvironment();
  print('Running in ${config.envName} -> ${config.apiUrl}');
}

कमांड लाइन पर Dart-Define पास करना

जब आप ऐप चलाते या बिल्ड करते हैं, तब कॉन्फ़िगरेशन शामिल करते हैं। प्रत्येक --dart-define एक कुंजी सेट करता है। इसे मूल फ़्लेवर के साथ --flavor द्वारा जोड़ी बनाकर उपयोग करें।

  • --flavor staging मूल रूपांतर (आईडी, आइकन, नाम) चुनता है।
  • --dart-define आपके AppConfig को मान देता है।

हर बार इन्हें टाइप करना गलतियों को आमंत्रित करता है, इसलिए टीमें इन्हें स्क्रिप्ट या फ़ाइलों में रखती हैं (अगला दृश्य)।

flutter run \
  --flavor staging \
  --target lib/main.dart \
  --dart-define=ENV=staging \
  --dart-define=API_URL=https://staging.api.acme.com \
  --dart-define=ANALYTICS=true

flutter build apk \
  --release \
  --flavor prod \
  --dart-define=ENV=prod \
  --dart-define=API_URL=https://api.acme.com \
  --dart-define=ANALYTICS=true

सुव्यवस्थित CI के लिए Dart-Define-From-File

लंबी --dart-define शृंखलाएँ नाज़ुक होती हैं। Flutter --dart-define-from-file का समर्थन करता है, जो कुंजी-मान युग्म वाली JSON (या .env-शैली) फ़ाइल पढ़ता है।

  • प्रत्येक एनवायरनमेंट के लिए एक फ़ाइल रखें: config/dev.json, config/staging.json, config/prod.json।
  • गैर-गोपनीय फ़ाइलों को कमिट करें; गोपनीय फ़ाइलों को CI में सुरक्षित भंडार से शामिल करें।

उदाहरण config/prod.json और उसका उपयोग दिखाया गया है। कुंजियाँ आपके fromEnvironment लुकअप से एक-से-एक मेल खाती हैं।

// config/prod.json
{
  "ENV": "prod",
  "API_URL": "https://api.acme.com",
  "ANALYTICS": true
}

// Invocation:
// flutter build appbundle --release \
//   --flavor prod \
//   --dart-define-from-file=config/prod.json

Android: productFlavors

Android पर फ़्लेवर android/app/build.gradle में घोषित करें। प्रत्येक फ़्लेवर ऐप्लिकेशन आईडी प्रत्यय और नाम को बदलता है, ताकि बिल्ड साथ-साथ इंस्टॉल हो सकें।

  • applicationIdSuffix मूल आईडी के अंत में जोड़ा जाता है (जैसे com.acme.app.dev)।
  • resValue प्रत्येक फ़्लेवर के लिए लॉन्चर लेबल बदलता है।

फ़्लेवर सूचीबद्ध करने से पहले flavorDimensions प्रविष्टि आवश्यक है।

android {
    flavorDimensions "env"
    productFlavors {
        dev {
            dimension "env"
            applicationIdSuffix ".dev"
            resValue "string", "app_name", "Acme Dev"
        }
        staging {
            dimension "env"
            applicationIdSuffix ".staging"
            resValue "string", "app_name", "Acme Staging"
        }
        prod {
            dimension "env"
            resValue "string", "app_name", "Acme"
        }
    }
}

iOS: Schemes और xcconfig

iOS पर फ़्लेवर, बिल्ड कॉन्फ़िगरेशन और .xcconfig फ़ाइलों पर आधारित Xcode स्कीम से जुड़े होते हैं। प्रत्येक स्कीम अलग PRODUCT_BUNDLE_IDENTIFIER और प्रदर्शित नाम सेट करती है।

  • Debug-dev, Release-prod जैसी कॉन्फ़िगरेशन बनाएँ।
  • प्रत्येक एनवायरनमेंट की .xcconfig फ़ाइल बंडल आईडी और DISPLAY_NAME को बदलती है; इन्हें $(DISPLAY_NAME) के माध्यम से Info.plist में पढ़ा जाता है।

Flutter --flavor prod को prod नाम वाली Xcode स्कीम से मिलाता है।

// ios/Flutter/staging.xcconfig
#include "Generated.xcconfig"
PRODUCT_BUNDLE_IDENTIFIER = com.acme.app.staging
DISPLAY_NAME = Acme Staging

// In Info.plist:
// <key>CFBundleDisplayName</key>
// <string>$(DISPLAY_NAME)</string>

प्रत्येक एनवायरनमेंट के अलग एसेट

फ़्लेवर को अक्सर अलग एसेट चाहिए होते हैं: रंगीन DEV बैनर, स्टेजिंग ऐप आइकन या अलग Firebase कॉन्फ़िगरेशन।

  • एसेट को assets/dev/, assets/prod/ जैसे फ़ोल्डर में व्यवस्थित करें और अपने AppConfig से रनटाइम पर पथ चुनें।
  • मूल आइकन के लिए Android src/dev/res को अपने-आप निर्धारित करता है; iOS प्रत्येक कॉन्फ़िगरेशन के एसेट कैटलॉग का उपयोग करता है।
  • फ़्लेवर-विशिष्ट google-services.json को android/app/src/<flavor>/ के अंतर्गत रखें।

Dart पक्ष केवल सक्रिय एनवायरनमेंट से एसेट पथ निकालता है।

class AssetPaths {
  final String envName;
  const AssetPaths(this.envName);

  String get logo => 'assets/$envName/logo.png';
  String get configBanner =>
      envName == 'prod' ? '' : 'assets/$envName/banner.png';
}

void main() {
  for (final env in ['dev', 'staging', 'prod']) {
    final paths = AssetPaths(env);
    print('$env logo: ${paths.logo}');
  }
}

AppConfig को main() से जोड़ना

स्टार्टअप पर कॉन्फ़िगरेशन एक बार निर्धारित करें और उसे विजेट ट्री के लिए उपलब्ध कराएँ (InheritedWidget, प्रदाता या सेवा लोकेटर के माध्यम से)। अपने विजेट में गहराई तक fromEnvironment पढ़ने से बचें।

  • runApp से पहले कॉन्फ़िगरेशन बनाएँ।
  • QA में भ्रम रोकने के लिए गैर-प्रोड बिल्ड में स्पष्ट एनवायरनमेंट बैनर दिखाएँ।

नीचे दिया गया स्निपेट Flutter फ़्रेमवर्क कोड है, इसलिए यह स्वतंत्र रूप से नहीं चल सकता, लेकिन यह मानक प्रवेश बिंदु दिखाता है।

import 'package:flutter/material.dart';

void main() {
  final config = AppConfig.fromEnvironment();
  runApp(MyApp(config: config));
}

class MyApp extends StatelessWidget {
  final AppConfig config;
  const MyApp({super.key, required this.config});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Acme (${config.envName})',
      debugShowCheckedModeBanner: !config.isProd,
      home: const Scaffold(body: Center(child: Text('Home'))),
    );
  }
}

त्वरित जाँच: कॉन्फ़िगरेशन कहाँ रहता है

आपने डेव, स्टेजिंग और प्रोड फ़्लेवर कॉन्फ़िगर कर लिए हैं। जाँचें कि Dart-define मान कैसे काम करते हैं, इसकी आपकी समझ कैसी है।

पुनरावलोकन

आपने फ़्लेवर और एनवायरनमेंट कॉन्फ़िगरेशन की पूरी रणनीति बनाई:

  • दो परतें: मूल फ़्लेवर (Android productFlavors, iOS स्कीम/xcconfig) ऐप की पहचान तय करते हैं; dart-define रनटाइम कॉन्फ़िगरेशन तय करता है।
  • टाइप सुरक्षा: एकल Environment enum और अपरिवर्तनीय AppConfig, जिसे AppConfig.fromEnvironment() के माध्यम से एक बार निर्धारित किया जाता है।
  • इंजेक्शन: --flavor को --dart-define के साथ पास करें, या --dart-define-from-file=config/<env>.json से सुव्यवस्थित रूप से विस्तार करें।
  • एसेट: आइकन, बैनर और Firebase कॉन्फ़िगरेशन के लिए प्रत्येक एनवायरनमेंट के अलग फ़ोल्डर और मूल संसाधन ओवरराइड।
  • मुख्य समझ: dart-define कंपाइल-समय पर बाइनरी में शामिल होता है, इसलिए कॉन्फ़िगरेशन बदलने का अर्थ हमेशा दोबारा बिल्ड करना है।

लाभ यह है कि डेव, स्टेजिंग और प्रोड साथ-साथ इंस्टॉल होते हैं, पूरी तरह अलग रहते हैं और उनमें भ्रम की कोई संभावना नहीं होती।

शुरुआत निःशुल्क

एआई शिक्षक के साथ Dart सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
22
पाठ
88

अक्सर पूछे जाने वाले प्रश्न

क्या “बिल्ड फ़्लेवर और पर्यावरण कॉन्फ़िगरेशन” पाठ निःशुल्क है?

हाँ — Flutter मोबाइल विकास अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “बिल्ड फ़्लेवर और पर्यावरण कॉन्फ़िगरेशन” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। Flutter मोबाइल विकास पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“बिल्ड फ़्लेवर और पर्यावरण कॉन्फ़िगरेशन” में मैं क्या सीखूँगा?

प्रत्येक पर्यावरण की एसेट और Dart-define कॉन्फ़िगरेशन के साथ dev, staging और prod फ़्लेवर परिभाषित कीजिए। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ Flutter मोबाइल विकास का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या Flutter मोबाइल विकास शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर Flutter मोबाइल विकास शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 1वाँ पाठ है।

“बिल्ड फ़्लेवर और पर्यावरण कॉन्फ़िगरेशन” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस Flutter मोबाइल विकास पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर Flutter मोबाइल विकास पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. बिल्ड फ़्लेवर और पर्यावरण कॉन्फ़िगरेशन
  2. Fastlane और GitHub Actions से स्वचालित पाइपलाइन
  3. क्रैश रिपोर्टिंग और प्रतीक-युक्त स्टैक ट्रेस
  4. रिमोट कॉन्फ़िगरेशन, सुविधा फ़्लैग और चरणबद्ध रिलीज़
← Flutter मोबाइल विकास पर वापस जाएँ