Flutter嵌入式配置插件embedded_config的使用

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter嵌入式配置插件embedded_config的使用

embedded_config 是一个允许在构建时将应用程序配置直接嵌入到源代码中的包。该插件旨在解决不同构建环境(例如开发环境和生产环境)需要不同应用程序配置的问题。通过使用 Dart 的构建系统(build_runner),可以为每个环境创建单独的 build.yaml 文件,并结合此包嵌入不同的配置。构建时,可以通过 build_runner--config 选项选择所需的环境。

目录


使用方法

1. 安装

embedded_config 依赖于 build_runner 包。为了避免将 build_runner 作为普通依赖项添加,embedded_config 提供了一个伙伴包 embedded_config_annotations

  • pubspec.yaml 中添加以下依赖项:
dependencies:
  embedded_config_annotations: ^0.3.0

dev_dependencies:
  embedded_config: ^0.4.0
  build_runner: ^2.0.0

2. 创建嵌入式配置类

配置是通过生成一个扩展抽象“嵌入式配置”类的类来嵌入到应用程序中的。生成的扩展类包含来自配置源的硬编码配置值。

  1. 创建一个带有 @EmbeddedConfig 注解的抽象类
    • 该类必须有一个默认的 const 构造函数。
    • 可以在类中定义抽象 getter,这些 getter 将映射到配置源中的键。
// file: app_config.dart

import 'package:embedded_config_annotations/embedded_config_annotations.dart';

// 添加生成的文件作为 part
part 'app_config.embedded.dart';

@EmbeddedConfig('app_config')
abstract class AppConfig {
  // 获取 API URL
  String get apiUrl;

  // 获取 Auth 配置
  AppAuthConfig get auth;

  // 必须声明一个默认的 const 构造函数
  const AppConfig();
}

// 由于这个类表示配置中的子对象,因此需要指定从配置根到该对象的路径
@EmbeddedConfig('app_config', path: ['auth'])
abstract class AppAuthConfig {
  // 获取客户端 ID,值将从环境变量 AUTH_CLIENT_ID 中获取
  String get clientId;

  const AppAuthConfig();
}
  1. 暴露生成的类
    • 可以通过 static const 单例方式暴露生成的类。
@EmbeddedConfig('app_config')
abstract class AppConfig {
  static const AppConfig instance = _$AppConfigEmbedded();

  String get apiUrl;
  AppAuthConfig get auth;

  const AppConfig();
}

3. 映射配置来源

接下来,我们需要实际的配置。配置可以指定在应用程序包中的配置文件或 build.yaml 文件中。有效的配置文件包括 JSON 和 YAML 格式的文件。

  1. build.yaml 中配置 embedded_config
    • 将配置源键(如 app_config)映射到 JSON 或 YAML 文件。
targets:
  $default:
    builders:
      embedded_config:
        options:
          # 将配置源键 'app_config' 映射到 'lib/app_config.json' 文件
          app_config: 'lib/app_config.json'
  1. 配置文件示例
    • 假设 app_config.json 文件内容如下:
{
  "apiUrl": "/api",
  "auth": {
    "clientId": "$AUTH_CLIENT_ID"
  }
}
  1. 生成的文件
    • 构建后,会生成一个名为 app_config.embedded.dart 的文件,其中包含硬编码的配置值。
part of 'app_config.dart';

class _$AppConfigEmbedded extends AppConfig {
  const _$AppConfigEmbedded();

  @override
  final apiUrl = '/api';

  @override
  final auth = _$AppAuthConfigEmbedded();
}

class _$AppAuthConfigEmbedded extends AppAuthConfig {
  const _$AppAuthConfigEmbedded();

  @override
  final clientId = 'your_client_id';  // 从环境变量 AUTH_CLIENT_ID 获取
}

合并配置

可以将多个配置源映射到同一个注解类。例如,可以定义一个基础的 app_config.json 文件和环境特定的 app_config.dev.jsonapp_config.prod.json 文件。在 build.dev.yaml 文件中,可以将 dev JSON 文件映射到基础文件上,而在 build.prod.yaml 文件中映射 prod 文件。

targets:
  $default:
    builders:
      embedded_config:
        options:
          app_config:
            source:
              - 'lib/app_config.json'
              - 'lib/app_config.dev.json'

内联配置来源

配置也可以直接在 build.yaml 文件中指定。这可以通过 inline 属性完成。

targets:
  $default:
    builders:
      embedded_config:
        options:
          app_config:
            inline:
              apiUrl: '/api2'

复杂配置模型

当配置不是扁平的键值对时,可以使用多个注解的嵌入式配置类。这通过设置 @EmbeddedConfig 注解的 path 属性来实现。path 是一个从配置根到所需子对象的配置键列表。

@EmbeddedConfig('app_config')
abstract class AppConfig {
  String get prop1;
  AppSubConfig get sub;

  const AppConfig();
}

@EmbeddedConfig('app_config', path: ['sub'])
abstract class AppSubConfig {
  String get prop2;
  AppSub2Config get sub2;

  const AppSubConfig();
}

@EmbeddedConfig('app_config', path: ['sub', 'sub2'])
abstract class AppSub2Config {
  String get prop3;

  const AppSub2Config();
}

环境变量

环境变量可以替换配置中的任何字符串值。这通过以 $ 开头的值来实现。例如,$BUILD_ID 将被替换为环境变量 BUILD_ID 的值。

转义环境变量

如果配置值以 $ 开头但不希望被替换为环境变量,可以使用 \ 进行转义。

{
  "value": "\$BUILD_ID"
}
示例:嵌入 CI 构建标识符

可以通过环境变量将 CI 构建标识符嵌入到应用程序中。

import 'package:embedded_config_annotations/embedded_config_annotations.dart';

@EmbeddedConfig('environment')
abstract class Environment {
  String get buildId;

  const Environment();
}

可以在 JSON 源中指定环境变量:

{
  "buildId": "$BUILD_ID"
}

或者在 build.yaml 中内联指定:

targets:
  $default:
    builders:
      embedded_config:
        options:
          environment:
            inline:
              buildId: '$BUILD_ID'

完整示例 Demo

假设我们有一个多级 JSON 配置文件 app_config.json,并且希望将其嵌入到应用程序中,同时使用环境变量。

1. 配置文件 app_config.json

{
  "apiUrl": "/api",
  "auth": {
    "clientId": "$AUTH_CLIENT_ID"
  }
}

2. Dart 类 app_config.dart

// file: lib/app_config.dart

import 'package:embedded_config_annotations/embedded_config_annotations.dart';

part 'app_config.embedded.dart';

@EmbeddedConfig('app_config')
abstract class AppConfig {
  static const AppConfig instance = _$AppConfigEmbedded();

  String get apiUrl;
  AppAuthConfig get auth;

  const AppConfig();
}

@EmbeddedConfig('app_config', path: ['auth'])
abstract class AppAuthConfig {
  String get clientId;

  const AppAuthConfig();
}

3. build.yaml 配置

targets:
  $default:
    builders:
      embedded_config:
        options:
          app_config: 'lib/app_config.json'

4. 使用配置

在应用程序中使用嵌入的配置:

void main() {
  print('API URL: ${AppConfig.instance.apiUrl}');
  print('Client ID: ${AppConfig.instance.auth.clientId}');
}

更多关于Flutter嵌入式配置插件embedded_config的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter嵌入式配置插件embedded_config的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用embedded_config插件进行嵌入式配置的示例代码。这个插件通常用于从外部源(如服务器或本地文件)加载配置信息,并将其注入到Flutter应用中。

首先,你需要在你的pubspec.yaml文件中添加embedded_config依赖:

dependencies:
  flutter:
    sdk: flutter
  embedded_config: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来获取依赖。

接下来,我们将编写一些代码来展示如何使用embedded_config插件。

1. 配置数据模型

首先,定义一个配置数据的模型类。假设我们的配置包含API的基础URL和一些其他设置:

// config_model.dart
class ConfigModel {
  final String apiBaseUrl;
  final String theme;

  ConfigModel({required this.apiBaseUrl, required this.theme});

  factory ConfigModel.fromJson(Map<String, dynamic> json) {
    return ConfigModel(
      apiBaseUrl: json['apiBaseUrl'] as String,
      theme: json['theme'] as String,
    );
  }
}

2. 加载配置

然后,我们编写一个方法来从外部源(例如,本地JSON文件或网络)加载配置,并使用embedded_config插件将其注入到应用中。

这里以从本地JSON文件加载配置为例:

// main.dart
import 'dart:convert';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:embedded_config/embedded_config.dart';
import 'config_model.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 假设你的配置文件名为config.json,位于assets文件夹下
  final String configAssetPath = 'assets/config.json';
  late ConfigModel configModel;

  // 从assets文件夹加载配置
  rootBundle.loadString(configAssetPath).then((String jsonString) async {
    final Map<String, dynamic> jsonMap = jsonDecode(jsonString);
    configModel = ConfigModel.fromJson(jsonMap);

    // 使用embedded_config插件设置全局配置
    await EmbeddedConfig.instance.set(key: 'config', value: configModel);

    // 运行应用
    runApp(MyApp());
  }).catchError((error) {
    print('Error loading config: $error');
    // 可以在这里处理错误,例如显示错误消息或使用默认配置
    configModel = ConfigModel(apiBaseUrl: 'https://default-api.com', theme: 'light');
    EmbeddedConfig.instance.set(key: 'config', value: configModel);
    runApp(MyApp());
  });
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    // 从embedded_config获取配置
    final ConfigModel? config = EmbeddedConfig.instance.get<ConfigModel>('config');
    if (config != null) {
      print('API Base URL: ${config.apiBaseUrl}');
      print('Theme: ${config.theme}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo Home Page'),
      ),
      body: Center(
        child: Text('Loading configuration...'),
      ),
    );
  }
}

3. 配置JSON文件

确保在assets文件夹中有一个名为config.json的文件,内容如下:

{
  "apiBaseUrl": "https://api.example.com",
  "theme": "dark"
}

并在pubspec.yaml中添加对assets文件夹的引用:

flutter:
  assets:
    - assets/config.json

4. 运行应用

现在,你可以运行你的Flutter应用,它将从config.json文件中加载配置,并使用embedded_config插件将其注入到应用中。

请注意,这只是一个基本示例。在实际应用中,你可能需要处理更多的错误情况,并从更复杂的源(如网络请求)加载配置。此外,embedded_config插件的具体用法可能会根据其版本和文档有所不同,因此请参考最新的官方文档以获取最佳实践。

回到顶部