繁体   English   中英

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

[英]How do I build different versions of my Flutter app for qa/dev/prod?

我正在构建一个 Flutter 应用程序,并且我有针对不同环境(QA、dev、prod 等)具有不同值的变量。 什么是组织我的应用程序以便我可以轻松地为 QA、开发、生产和其他环境构建的好方法?

基于 Seth 的想法,这里有一个示例,该示例设置了一个表示名为envBuildEnvironment的全局BuildEnvironment

环境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());
}
  • 导入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"
    }
  ]
}

我最初打算使用传递给 Dart 的main函数的命令行参数,但我不认为 args 目前可以通过flutter runflutter build在命令行上传递,尽管 VS Code 和 Android Studio 都支持将 args 传递给main . 似乎构建风格作为main的命令行 arg 是不合适的,因为 args 可以在构建过程之后传递。

发布和调试模式现在可以使用

const bool isProduction = bool.fromEnvironment('dart.vm.product');

因为这是一个常数,所以它适用于摇树。
所以代码就像

if(isProduction) {
  // branch 1
} else {
  // branch 2
}

根据isProduction只会将这两个分支之一包含到生产代码中

一种方法是:在项目的lib/目录中创建不同的main_<environment>.dart文件。

每个main_<environment>.dart包含特定于环境的配置/值(例如不同的数据库名称等)。 然后每个main_<environment>.dart导入实际的应用程序库并运行应用程序,传入环境的值/配置。

然后,选择要构建的.dart文件: flutter run -t lib/main_debug.dart

从 Flutter 1.17 开始,您可以使用--dart-define来构建具有不同编译时变量的应用程序。 它适用于 Dart 和原生层。 例如,在 dart 中,您可以使用String.fromEnvironment获得这些值。 通过这种方式,您将不需要大量或入口点并公开您的环境凭据

这是一篇解释更多的文章https://link.medium.com/ibuTsWHrk6

import 'package:flutter/foundation.dart';

并使用以下常量值:

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.
}

您可以简单地实现构建变体。

在安卓中:

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"
  }
}

在 iOS 中:

通过选择 project->runner->configuration add one more 来添加配置

2019 年 7 月更新:

我写了一个集成了 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

++++ 旧答案++++

附加信息:

我遇到了同样的问题并使用了 Seth Ladd 建议的解决方案。 因此,我还需要为每个应用程序版本(dev/prod)进行不同的配置,我不想在 main_dev.dart 或 main_prod.dart 文件中编写配置。

我编写了一个简单的 flutter 包,用于处理分离的配置文件并在应用程序启动时加载它们。 然后在您的应用程序中的每一行代码中都可以使用该配置。

https://github.com/Ephenodrom/Flutter-Global-Config

如何使用它:

在assets/cfg/$file.json下创建一个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"));
     }
}

更简洁的方法是通过Build Flavors

举一个简单的例子,如果你想为你的“开发”构建的应用程序使用不同的应用程序 ID,你可以在 gradle 文件中包含它:

flavorDimensions "version"
productFlavors {
    dev {
        applicationIdSuffix ".dev"
        versionNameSuffix "-dev"
    }
}

在此处阅读有关 gradle 构建变体配置的更多信息。


现在您可以使用命令行运行此构建变体:

flutter run --flavor dev

如果您使用的是 Android Studio,您也可以在运行配置中设置构建变体:

在此处输入图片说明

在此博客上阅读有关 iOS 配置的更多信息。 以及关于构建风格的官方颤振文档。

想法是为构建类型继承小部件(我的是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://stackoverflow.com/a/47438620/2719243

一步一步: https//iirokrankka.com/2018/03/02/separating-build-environments/

在项目app_environment.dart的根目录创建一个文件。 使用来自foundation.dart包的kReleaseMode变量来检查生产模式。

import 'package:flutter/foundation.dart';

class AppEnvironment {

  String getApiURL() {
    if (kReleaseMode) {
      return 'PROD_API_URL';
    } else {
      return 'STAGING_API_URL';
    }
  }
}

由于 macOS 不支持风格,您可能对这种适用于所有平台的简单、简洁和实用的方法感兴趣:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM