今天咱们聊个简略的知识点,在 Flutter 3.7 的 release-notes 里,有一个没有出现在 announcement 阐明上的 change log ,可能关于 Flutter 团队来说这个功用并不是特别重要,可是关于我个人而言,这是一个十分重要的才能弥补:

  • [flutter_tools] Fix so that the value set by --dart-define-from-file can be passed to Gradle by @blendthink in github.com/flutter/flu…

翻到这个小功用,纯属是意外之喜。

Dart

在 3.7 版别之前,假如咱们需求在编译时动态给 Flutter 增加变量信息,那么咱们会用到 --dart-define ,例如:

flutter run --dart-define=APP_CHANNEL=Offical
const APP_CHANNEL = String.fromEnvironment('APP_CHANNEL');

咱们能够经过 --dart-define 在指令行指定一个变量,然后在 Flutter 里经过 String.fromEnvironment 读取它,一般场景下它是满意需求的,可是:

  • 假如当你需求界说多个变量时,指令就会变得冗长且不好保护

  • 假如你是混合开发,变量还需求同步修正到原生项目的装备里,就会变得费事

在此之前,针对同步修正到不同原生项目的装备,我是经过自界说脚本去完成:

  • Android 上运用 gradle 脚本,参考 RN 上的 dotenv 读取某个脚本装备,修正 project.env
  • iOS 上经过读取脚本装备,然后运用体系的 PlistBuddy 指令在编译时刺进和修正某些参数

而现在,从 Flutter 3.7 开端,它变得更简略了,由于你能够运用 --dart-define-from-file

flutter run --dart-define-from-file=config.json
////// config.json ////// 
{
  "TEST_KEY1": "test key 1",
  "TEST_KEY2": "test key 2"
}  

相同是 dart define ,可是 --dart-define-from-file 能够直接从一个 json 文件上读取装备,然后转成一个 Map,之后装备到 Environment 里,相同是能够在 dart 里经过 String.fromEnvironment 去读取参数,而 json 文件的装备方式,能够让你在需求装备多个变量时参数管理变得更好保护。

Flutter 小技巧之 3.7 更灵活的编译变量支持

那到这儿就结束了吗?显然不是,前面咱们说过同步修正到不同原生项目的装备,而 Flutter 3.7 下官方也正式支撑。

Android

首先是 Android ,咱们能够在 app/build.gradle 文件下界说一个 dartEnvVar 变量,它主要是用来读取前面 json 文件注入到 project 的参数。

Flutter 小技巧之 3.7 更灵活的编译变量支持

然后咱们就能够在 app/build.gradle 下直接经过 dartEnvVar 引证对应参数,比方界说 resValue ,能够看到 dartEnvVar 在编译时,成功读取到 json 文件里的参数。

Flutter 小技巧之 3.7 更灵活的编译变量支持
Flutter 小技巧之 3.7 更灵活的编译变量支持

如下图所示,能经过 project 读取 dart 的环境变量装备之后,咱们就能够界说有 resValue 去修正 AndroidManifest 文件,甚至界说刺进到 BuildConfig 里在原生代码引证,而关于装备咱们只需求保护一份 json 文件即可。

Flutter 小技巧之 3.7 更灵活的编译变量支持

那它是怎么完成的?简略来说,在 flutter/packages/flutter_tools/lib/src/build_info.dart 脚本下,之前读取的 json 文件能够得到一个 dartDefineConfigJsonMap 目标,它会被转化为一个 Gradle 参数列表,在之后的 assembleTask 里被作为参数履行。

这儿需求留意,界说的 key 不能和与定制的 key 冲突,比方 dart-obfuscation 等。

Flutter 小技巧之 3.7 更灵活的编译变量支持

如下图所示,终究履行的时分就会是 -PTEST_KEY1=test key 1 -PTEST_KEY2=test key 2 这样的效果。

Flutter 小技巧之 3.7 更灵活的编译变量支持

iOS

iOS 上相同也很简略,你只需求在 Info.plist 上界说好 key-value 的引证即可,由于 iOS 上在 --dart-define-from-file 编译时,相同会生成对应的 xcconfig 装备信息。

Flutter 小技巧之 3.7 更灵活的编译变量支持

ios/Flutter 目录下,编译时会产生两个疏忽文件,分别是 flutter_export_environment.shGenerated.xcconfig ,能够看到编译后这两个文件下都产生了对应的 key-value 。

Flutter 小技巧之 3.7 更灵活的编译变量支持
Flutter 小技巧之 3.7 更灵活的编译变量支持

这儿需求留意,在 iOS 上 xcconfig 格局会将 // 读取为注释分隔符 ,也便是 // 之后的内容会被疏忽,也便是说,你不能经过它来传递 url ,比方 https://xxxx ,由于 // 后会被疏忽。

当然,假如你需求默认值,那么你也能够在 ios/Flutter 目录下的 Debug.xcconfigRelease.xcconfig 上进行定制装备。

Flutter 小技巧之 3.7 更灵活的编译变量支持

和 Android 一样, iOS 在编译时会对 --dart-define-from-file 的参数进行转化变成 xcconfig 参数,然后完成 dart 和 iOS 端公用一份变量装备的效果。

Flutter 小技巧之 3.7 更灵活的编译变量支持
Flutter 小技巧之 3.7 更灵活的编译变量支持

最终

能够看到 --dart-define-from-file 的运用和完成并不复杂,在没有它之前咱们也能够经过一些手段来完成相似的效果。

可是 --dart-define-from-file 指令的出现简化了整个构建流程,让编译动态装备的链条变得更加灵活可靠,所以它无疑是 3.7 里最容易被疏忽的有用更新。

不得不说,Flutter 3.7 给咱们带来了不少的惊喜,例如 toImageSync 和 background isolate 都是期待已久的功用,而相似 --dart-define-from-file 的支撑,也在不断完善 Flutter 的开发体会。

最终,从 3.7 开端的小版别更新有两个特征:

  • 1、impeller 确实还有不少问题
  • 2、impeller 真的来了,就算预览功用也要 fix 到稳定分支

Flutter 小技巧之 3.7 更灵活的编译变量支持

期待下个版别 impeller 能给咱们带来更好的体会。