Home Coding การตั้งค่าให้ Flutter รันแยก Environment

การตั้งค่าให้ Flutter รันแยก Environment

by khomkrit

โดยทั่วไปเวลาเราทำแอปแล้วต้องต่อเข้ากับ API หลังบ้าน เราก็จะต้องแยก environment เพื่อไม่ให้ข้อมูลสำหรับทดสอบกับของจริงปนกัน ส่วนจะแยกเป็นกี่ environment นั้นก็แล้วแต่ทีมจะกำหนดกันเองอีกที เช่น dev, staging, และ production เป็นต้น ซึ่งการแยก environment แบบนี้ใน Android จะเรียกว่า Flavor ส่วนใน iOS จะเรียกว่า Target/Scheme

แนวคิดของการแยก Environment ก็คือการแยก main file ที่เราจะใช้เรียกตอนรันโปรแกรมนั่นเอง โดยเราจะแยกไปตามแต่ละ environment เลย เช่น ถ้าเรามี 2 enviroment คือ dev กับ prod เราก็อาจสร้าง 2 main ไฟล์แยกกันดังนี้

  • main_dev.dart
  • main_prod.dart

ซึ่งแต่ละ main file ก็จะมี configuration ที่แตกต่างกัน โดยเราจะสร้าง configuration file แยกออกมา และส่งไปให้แต่ละ main file ใช้งานอีกที

เราลองมาดู main_dev.dart, main_prod.dart, และไฟล์ app_config.dart กันก่อน

import 'package:flutter_flavors/config/app_config.dart';
import 'package:flutter_flavors/config/app_config_dev.dart';
import 'package:flutter_flavors/main_common.dart';

void main() {
  final AppConfig appConfig = AppConfigDev();
  runApp(MyApp(
    appConfig,
  ));
}
import 'package:flutter_flavors/config/app_config.dart';
import 'package:flutter_flavors/config/app_config_prod.dart';
import 'package:flutter_flavors/main_common.dart';

void main() {
  final AppConfig appConfig = AppConfigProd();
  runApp(MyApp(
    appConfig,
  ));
}

เราใช้ app_config.dart สำหรับประกาศว่า configuration ควรจะต้องมี attribute อะไรให้ config บ้าง ในที่นี้คือมีค่าเดียว appName

import 'package:flutter/material.dart';

abstract class AppConfig {
  String get appName;
}

มาถึงตรงนี้เราก็มีคลาสพร้อมใช้งานแล้ว ขั้นตอนต่อไปก็คือการ config แต่ละ environment โดยการ extends AppConfig มาใช้งาน โดยการสร้างไฟล์ app_config_dev.dart กับ app_config_prod.dart แยกออกมาดังนี้

import 'package:flutter/material.dart';
import 'package:flutter_flavors/config/app_config.dart';

class AppConfigDev implements AppConfig {
  final _appName = "My App(DEV)";

  @override
  String get appName => _appName;
}

import 'package:flutter/material.dart';
import 'package:flutter_flavors/config/app_config.dart';

class AppConfigProd implements AppConfig {
  final _appName = "Dog Match";

  @override
  String get appName => _appName;
}

จากตัวอย่าง เราใช้วิธีส่ง configuration ลงไปให้ MyApp ใช้ แต่จริงๆ แล้วเราสามารถใช้ library ที่ทำ dependency injection อย่าง Provider หรือ Flutter BLoC ก็ได้ ซึ่งนั่นทำให้เราสามารถอ้างอึง config ของเราได้จากที่ไหนในแอปก็ได้โดยสะดวก

แต่ในบทความนี้ไม่ได้ใช้ เพราะต้องการลดความซับซ้อนของโค้ดลง

ส่วนใน MyApp เราก็สามารถเรียกใช้ค่าใน config ได้เลยตรงๆ แบบนี้

import 'package:flutter/material.dart';
import 'package:flutter_flavors/config/app_config.dart';

class MyApp extends StatefulWidget {
  MyApp(this.appConfig);

  final AppConfig appConfig;

  @override
  _MyAppState createState() => _MyAppState(appConfig);
}

class _MyAppState extends State<DogApp> {
  _MyAppState(this.appConfig);

  final AppConfig appConfig;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(Text(appConfig.appName)),
      )
    )
  }
}

ทีนี้เวลาเราต้องการรันแยก main file เราสามารถรันโดยใช้ -t เพื่อระบุว่าจะให้ไฟล์ไหนเป็นไฟล์แรกได้เลยแบบนี้

$ flutter run -t lib/main_dev.dart
or
$ flutter run -t lib/main_prod.dart

ถ้าต้องการ config ให้รันแยกกันใน VS Code ให้เลือกเมนู Run → Add Configuration ดังนี้

จากนั้นก็ config แยกกันตาม environment ได้เลย

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "My App (DEV)",
            "request": "launch",
            "type": "dart",
            "program": "lib/main_dev.dart",
        },
        {
            "name": "My App",
            "request": "launch",
            "type": "dart",
            "program": "lib/main_prod.dart",
        }
    ]
}

เมื่อเราเข้าไปดูในเมนู Run ที่อยู่ทางซ้ายของ VS Code ก็จะเห็นคำสั่งตามชื่อที่เราตั้งไว้ในไฟล์ launch.json

อย่างไรก็ตามบทความนี้นำเสนอแค่การ config แยก environment อย่างง่ายๆ เท่านั้น หากต้องการ config แยกกันในระดับที่ละเอียดกว่านี้ เช่น มี App Icon, App Name, หรือ App ID ที่แตกต่างกันในแต่ละ environment เราสามารถอ่านเพิ่มเติมได้ที่ Creating flavors for Flutter

บทความนี้ใช้ Code และรูปจาก Rafael Delos Santos

You may also like

1 comment

Comments are closed.