[英]How do I build different versions of my Flutter app for qa/dev/prod?
I am building a Flutter app, and I have variables with different values for different environments (QA, dev, prod, etc).我正在构建一个 Flutter 应用程序,并且我有针对不同环境(QA、dev、prod 等)具有不同值的变量。 What's a good way to organize my app so I can easily make a build for QA, dev, prod, and other environments?
什么是组织我的应用程序以便我可以轻松地为 QA、开发、生产和其他环境构建的好方法?
Building on Seth's idea, here's an example that sets up a global representing the BuildEnvironment
named env
.基于 Seth 的想法,这里有一个示例,该示例设置了一个表示名为
env
的BuildEnvironment
的全局BuildEnvironment
。
env.dart环境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 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 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());
}
env.dart
to expose the env
variable.env.dart
以公开env
变量。 run and build the app using the target
option.使用
target
选项运行和构建应用程序。
flutter run -t lib/main_dev.dart flutter build -t lib/main_dev.dart
To integrate with VS Code, define launch configurations:要与 VS Code 集成,请定义启动配置:
.vscode/launch.json .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"
}
]
}
I had originally set out to use command line arguments passed to Dart's main
function, but I don't think args can currently be passed on the command line with flutter run
or flutter build
, although VS Code and Android Studio both support passing args to main
.我最初打算使用传递给 Dart 的
main
函数的命令行参数,但我不认为 args 目前可以通过flutter run
或flutter build
在命令行上传递,尽管 VS Code 和 Android Studio 都支持将 args 传递给main
. It also seems build flavor as a command line arg to main
is not appropriate since args can be passed after the build process.似乎构建风格作为
main
的命令行 arg 是不合适的,因为 args 可以在构建过程之后传递。
Release and debug mode can now be acquired using发布和调试模式现在可以使用
const bool isProduction = bool.fromEnvironment('dart.vm.product');
Because this is a constant it works with tree-shaking.因为这是一个常数,所以它适用于摇树。
So code like所以代码就像
if(isProduction) {
// branch 1
} else {
// branch 2
}
would only include one of these two branches into production code depending on isProduction
根据
isProduction
只会将这两个分支之一包含到生产代码中
One way to do it: create different main_<environment>.dart
files in the lib/
directory of your project.一种方法是:在项目的
lib/
目录中创建不同的main_<environment>.dart
文件。
Each main_<environment>.dart
contains the environment-specific configurations/values (such as the different database names, etc).每个
main_<environment>.dart
包含特定于环境的配置/值(例如不同的数据库名称等)。 Each main_<environment>.dart
then imports the actual application library and runs the application, passing in the environment's values/configurations.然后每个
main_<environment>.dart
导入实际的应用程序库并运行应用程序,传入环境的值/配置。
Then, choose which .dart
file to build: flutter run -t lib/main_debug.dart
然后,选择要构建的
.dart
文件: flutter run -t lib/main_debug.dart
Starting from Flutter 1.17 you can use --dart-define
to build your app with different compile time variables.从 Flutter 1.17 开始,您可以使用
--dart-define
来构建具有不同编译时变量的应用程序。 It works for both Dart and native layers.它适用于 Dart 和原生层。 In dart you get these values with
String.fromEnvironment
for example.例如,在 dart 中,您可以使用
String.fromEnvironment
获得这些值。 In that way you won't need to have tons or entry points and expose your environment credentials通过这种方式,您将不需要大量或入口点并公开您的环境凭据
Here is an article that explains more https://link.medium.com/ibuTsWHrk6这是一篇解释更多的文章https://link.medium.com/ibuTsWHrk6
import 'package:flutter/foundation.dart';
And use following const values:并使用以下常量值:
if (kReleaseMode) {
// App is running in release mode.
} else if (kProfileMode) {
// App is running in profile mode.
} else if (kDebugMode) {
// App is running in debug mode.
} else if (kIsWeb) {
// App is running on the web.
}
Simply you can implement build variants.您可以简单地实现构建变体。
In android:在安卓中:
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
}
}
productFlavors {
dev {
dimension "app"
resValue "string", "app_name", "xyz Dev"
applicationId "com.xyz.dev"
}
prod {
dimension "app"
resValue "string", "app_name", "xyz"
}
}
In iOS :在 iOS 中:
add configuration by selecting project->runner-> configuration add one more通过选择 project->runner->configuration add one more 来添加配置
Update July 2019 : 2019 年 7 月更新:
I wrote a Package that integrates the Flutter Global Config.我写了一个集成了 Flutter 全局配置的包。
EZ Flutter is a collection of widgets, packages and many more usefull things, mixed up in little framework. EZ Flutter 是小部件、包和许多更有用的东西的集合,混合在小框架中。 The aim is to make standard features available from scratch.
目的是从头开始提供标准功能。
Github : https://github.com/Ephenodrom/EZ-Flutter Github: https : //github.com/Ephenodrom/EZ-Flutter
dependencies:
ez_flutter: ^0.2.0
Check out the documentation how using different configurations works.查看文档如何使用不同的配置。
https://github.com/Ephenodrom/EZ-Flutter/blob/master/documentation/APPLICATION_SETTINGS.md https://github.com/Ephenodrom/EZ-Flutter/blob/master/documentation/APPLICATION_SETTINGS.md
++++ OLD ANSWER ++++ ++++ 旧答案++++
Additional information :附加信息:
I had the same problem and used the solution suggested by Seth Ladd.我遇到了同样的问题并使用了 Seth Ladd 建议的解决方案。 Therefore I also needed different configuration for each app version (dev / prod ) and i don't want to write the configuration in the main_dev.dart or in the main_prod.dart file.
因此,我还需要为每个应用程序版本(dev/prod)进行不同的配置,我不想在 main_dev.dart 或 main_prod.dart 文件中编写配置。
I wrote a simple flutter package that deals with having seperated configuration files and load them at app startup.我编写了一个简单的 flutter 包,用于处理分离的配置文件并在应用程序启动时加载它们。 The configuration is then available at each line of code in your app.
然后在您的应用程序中的每一行代码中都可以使用该配置。
https://github.com/Ephenodrom/Flutter-Global-Config https://github.com/Ephenodrom/Flutter-Global-Config
How to use it :如何使用它:
Create a json file under assets/cfg/$file.json在assets/cfg/$file.json下创建一个json文件
Add assets/cfg to your pubspec.yaml将 assets/cfg 添加到您的 pubspec.yaml
Loading different configuration files at app start :在应用程序启动时加载不同的配置文件:
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 {
...
}
Using the configuration in your app :在您的应用程序中使用配置:
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"));
}
}
The cleaner way to do this is through Build Flavors .更简洁的方法是通过Build Flavors 。
As a quick example, if you want to have a different app id for your app for your "dev" build, you could have this in the gradle file:举一个简单的例子,如果你想为你的“开发”构建的应用程序使用不同的应用程序 ID,你可以在 gradle 文件中包含它:
flavorDimensions "version"
productFlavors {
dev {
applicationIdSuffix ".dev"
versionNameSuffix "-dev"
}
}
Read more about gradle build variant configuration here .在此处阅读有关 gradle 构建变体配置的更多信息。
Now you can run with this build variant with command line:现在您可以使用命令行运行此构建变体:
flutter run --flavor dev
If you are using Android Studio, you can set the build variant in the Run configuration too:如果您使用的是 Android Studio,您也可以在运行配置中设置构建变体:
Read more about iOS configuration on this blog .在此博客上阅读有关 iOS 配置的更多信息。 And official flutter documentation about build flavours .
以及关于构建风格的官方颤振文档。
idea is to have inherited widget for build types ( mine is DEV , STAGE , PRO ) and have 3 type config to run! 想法是为构建类型继承小部件(我的是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;
}
so we have in main : 所以我们主要有:
void main() {
var configuredApp = AppConfig(
appName: 'DEV',
flavorName: 'develop',
apiBaseUrl: 'https://dev-api.example.com/',
child: new MyApp(),
);
runApp(configuredApp);
}
this is good answer and also this page worked for me . 这是一个很好的答案,这个页面也适合我。
https://stackoverflow.com/a/47438620/2719243 https://stackoverflow.com/a/47438620/2719243
step by step : https://iirokrankka.com/2018/03/02/separating-build-environments/ 一步一步: https : //iirokrankka.com/2018/03/02/separating-build-environments/
Create a file at the root of the project app_environment.dart
.在项目
app_environment.dart
的根目录创建一个文件。 Use the kReleaseMode
variable from foundation.dart
package to check for production mode.使用来自
foundation.dart
包的kReleaseMode
变量来检查生产模式。
import 'package:flutter/foundation.dart';
class AppEnvironment {
String getApiURL() {
if (kReleaseMode) {
return 'PROD_API_URL';
} else {
return 'STAGING_API_URL';
}
}
}
Since flavors are not supported on macOS you may be interested in this easy, clean and pragmatic approach, which works for all platforms:由于 macOS 不支持风格,您可能对这种适用于所有平台的简单、简洁和实用的方法感兴趣:
https://medium.com/software-development-at-skalio/how-to-separate-test-and-production-environments-in-flutter-e915e3125525 https://medium.com/software-development-at-skalio/how-to-separate-test-and-production-environments-in-flutter-e915e3125525
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.