Я создаю приложение Flutter, и у меня есть переменные с разными значениями для разных сред (QA, dev, prod и т.д.). Какой хороший способ организовать мое приложение, чтобы я мог легко создать сборку для QA, dev, prod и других сред?
Как создать различные версии моего приложения Flutter для qa/dev/prod?
Ответ 1
Один из способов сделать это: создать различные main_<environment>.dart
каталоге lib/
вашего проекта.
Каждый main_<environment>.dart
содержит конфигурационные параметры/значения, специфичные для среды (например, имена разных баз данных и т.д.). Каждый main_<environment>.dart
затем импортирует фактическую библиотеку приложений и запускает приложение, передавая значения/конфигурации среды.
Затем выберите, какой файл .dart
для сборки: flutter run -t lib/main_debug.dart
Ответ 2
Основываясь на идее Сета, вот пример, который устанавливает глобальное представление BuildEnvironment
именем env
.
env.dart
import 'package:meta/meta.dart';
enum BuildFlavor { production, development, staging }
BuildEnvironment get env => _env;
BuildEnvironment _env;
class BuildEnvironment {
/// The backend server.
final String baseUrl;
final BuildFlavor flavor;
BuildEnvironment._init({this.flavor, this.baseUrl});
/// Sets up the top-level [env] getter on the first call only.
static void init({@required flavor, @required baseUrl}) =>
_env ??= BuildEnvironment._init(flavor: flavor, baseUrl: baseUrl);
}
main_dev.dart
import 'package:flutter/material.dart';
import 'env.dart';
import 'app.dart';
void main() {
BuildEnvironment.init(
flavor: BuildFlavor.development, baseUrl: 'http://dev.example.com');
assert(env != null);
runApp(App());
}
main_prod.dart
import 'package:flutter/material.dart';
import 'env.dart';
import 'app.dart';
void main() {
BuildEnvironment.init(
flavor: BuildFlavor.production, baseUrl: 'http://example.com');
assert(env != null);
runApp(App());
}
- import
env.dart
чтобы открыть переменнуюenv
. -
запустить и создать приложение, используя
target
параметр.flutter run -t lib/main_dev.dart flutter build -t lib/main_dev.dart
Для интеграции с VS Code определите конфигурации запуска:
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "development",
"program": "lib/main_dev.dart",
"request": "launch",
"type": "dart"
},
{
"name": "production",
"program": "lib/main_prod.dart",
"request": "launch",
"type": "dart"
}
]
}
Я изначально собирался использовать аргументы командной строки, переданные main
функции Dart, но я не думаю, что в командной строке можно передавать аргументы в командной строке с помощью flutter run
или flutter build
, хотя VS Code и Android Studio поддерживают передачу аргументов main
, Это также кажется, что компоновка компоновки в качестве командной строки arg main
не подходит, поскольку args могут быть переданы после процесса сборки.
Ответ 3
Режим освобождения и отладки теперь можно получить, используя
const bool isProduction = bool.fromEnvironment('dart.vm.product');
Поскольку это константа, она работает с дрожанием дерева.
Так что код вроде
if(isProduction) {
// branch 1
} else {
// branch 2
}
будет включать только один из этих двух ветвей в производственный код в зависимости от isProduction
Ответ 4
Просто вы можете реализовать варианты сборки.
В андроиде:
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so 'flutter run --release' works.
signingConfig signingConfigs.release
}
debug{
applicationIdSuffix ".dev"
signingConfig signingConfigs.debug
}
qa{
applicationIdSuffix ".qa"
signingConfig signingConfigs.qa
}
}
В iOS:
добавьте конфигурацию, выбрав project-> runner-> configuration, добавьте еще один
Ответ 5
Обновление от июля 2019 года:
Я написал пакет, в который интегрирована глобальная конфигурация Flutter.
EZ Flutter - это коллекция виджетов, пакетов и многих других полезных вещей, смешанных в небольшом фреймворке. Цель состоит в том, чтобы сделать стандартные функции доступными с нуля.
Github: https://github.com/Ephenodrom/EZ-Flutter
dependencies:
ez_flutter: ^0.2.0
Ознакомьтесь с документацией о том, как работают различные конфигурации.
https://github.com/Ephenodrom/EZ-Flutter/blob/master/documentation/APPLICATION_SETTINGS.md
++++ СТАРЫЙ ОТВЕТ ++++
Дополнительная информация:
У меня была та же проблема, и я использовал решение, предложенное Сетом Лэддом. Поэтому мне также требовались разные конфигурации для каждой версии приложения (dev/prod), и я не хочу записывать конфигурацию в файл main_dev.dart или main_prod.dart.
Я написал простой пакет флаттера, который имеет дело с разделением файлов конфигурации и загрузкой их при запуске приложения. Конфигурация будет доступна в каждой строке кода в вашем приложении.
https://github.com/Ephenodrom/Flutter-Global-Config
Как это использовать:
Создайте файл json в assets/cfg/$ file.json
Добавьте assets/cfg в ваш pubspec.yaml
Загрузка различных файлов конфигурации при запуске приложения:
import 'package:flutter/material.dart';
import 'package:global_configuration/global_configuration.dart';
void main() async{
await GlobalConfiguration().loadFromAsset("app_settings");
await GlobalConfiguration().loadFromAsset("env_dev_settings");
runApp(MyApp());
}
class MyApp extends StatelessWidget {
...
}
Использование конфигурации в вашем приложении:
import 'package:flutter/material.dart';
import 'package:global_configuration/global_configuration.dart';
class CustomWidget extends StatelessWidget {
CustomWiget(){
// Access the config in the constructor
print(GlobalConfiguration().getString("key1"); // prints value1
}
@override
Widget build(BuildContext context) {
// Access the config in the build method
return new Text(GlobalConfiguration().getString("key2"));
}
}
Ответ 6
Идея состоит в том, чтобы унаследовать виджет для типов сборки (у меня DEV, STAGE, PRO) и иметь конфигурацию 3 типов для запуска!
class AppConfig extends InheritedWidget {
var flavorName;
var apiBaseUrl;
var appName;
AppConfig(
{@required this.appName,
@required this.flavorName,
@required this.apiBaseUrl,
@required Widget child})
: super(child: child);
static AppConfig of(BuildContext context) {
return context.inheritFromWidgetOfExactType(AppConfig);
}
@override
bool updateShouldNotify(InheritedWidget oldWidget) => false;
}
так что мы имеем в основном:
void main() {
var configuredApp = AppConfig(
appName: 'DEV',
flavorName: 'develop',
apiBaseUrl: 'https://dev-api.example.com/',
child: new MyApp(),
);
runApp(configuredApp);
}
это хороший ответ, и эта страница сработала для меня.
шаг за шагом: https://iirokrankka.com/2018/03/02/separating-build-environments/