简体   繁体   English

如何为 qa/dev/prod 构建不同版本的 Flutter 应用程序?

[英]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 的想法,这里有一个示例,该示例设置了一个表示名为envBuildEnvironment的全局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());
}
  • import 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 runflutter 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);
 }

then : 然后 : 在此输入图像描述

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.

相关问题 Firebase:如何在应用检查中注册我的 Flutter 应用? - Firebase: How do I register my Flutter app in app check? 如何以编程方式从我的 Flutter 应用程序启动应用程序? - How do I launch an app from my Flutter app programmatically? Dart Package 版本如何工作以及我应该如何对我的 Flutter 插件进行版本控制? - How do Dart Package Versions work & how should I version my Flutter Plugins? 如何修复我的 dart 开发工具? (Flutter Android 许可证 - 错误 65) - How do I fix my dart dev tools? (Flutter Android License - Error 65 ) Flutter-如何创建一个我可以拥有Debug和Prod版本的框架,其中debug版本可以选择测试环境 - Flutter - how to create a framework where i can have Debug and Prod versions where debug version has some way to choose test environment 如何在我的 Flutter 应用程序中添加渐变背景? - How do I add a gradient background in my flutter app? 如何在我的 Flutter 应用程序中保存列表中的项目? - How do I save the items in the list in my flutter app? 如何修复未使用 Cloud Firestore 构建的颤振应用程序? - how do I fix my flutter app not building with cloud firestore? 如何在我的 flutter 选项卡式应用程序中使用图像 - How do I use an image in my flutter tabbed app 如何从我的热点在 Chrome 上运行 Flutter 应用程序? - How do I run a Flutter app on Chrome from my hotspot?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM