今天咱们聊个简略的知识点,在 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 下官方也正式支撑。
Android
首先是 Android ,咱们能够在 app/build.gradle
文件下界说一个 dartEnvVar
变量,它主要是用来读取前面 json 文件注入到 project
的参数。
然后咱们就能够在 app/build.gradle
下直接经过 dartEnvVar
引证对应参数,比方界说 resValue
,能够看到 dartEnvVar
在编译时,成功读取到 json 文件里的参数。
如下图所示,能经过 project
读取 dart 的环境变量装备之后,咱们就能够界说有 resValue
去修正 AndroidManifest
文件,甚至界说刺进到 BuildConfig
里在原生代码引证,而关于装备咱们只需求保护一份 json 文件即可。
那它是怎么完成的?简略来说,在 flutter/packages/flutter_tools/lib/src/build_info.dart 脚本下,之前读取的 json 文件能够得到一个 dartDefineConfigJsonMap
目标,它会被转化为一个 Gradle 参数列表,在之后的 assembleTask
里被作为参数履行。
这儿需求留意,界说的 key 不能和与定制的 key 冲突,比方
dart-obfuscation
等。
如下图所示,终究履行的时分就会是 -PTEST_KEY1=test key 1 -PTEST_KEY2=test key 2 这样的效果。
iOS
iOS 上相同也很简略,你只需求在 Info.plist
上界说好 key-value 的引证即可,由于 iOS 上在 --dart-define-from-file
编译时,相同会生成对应的 xcconfig
装备信息。
在 ios/Flutter
目录下,编译时会产生两个疏忽文件,分别是 flutter_export_environment.sh
和 Generated.xcconfig
,能够看到编译后这两个文件下都产生了对应的 key-value 。
这儿需求留意,在 iOS 上
xcconfig
格局会将//
读取为注释分隔符 ,也便是//
之后的内容会被疏忽,也便是说,你不能经过它来传递 url ,比方https://xxxx
,由于//
后会被疏忽。
当然,假如你需求默认值,那么你也能够在 ios/Flutter
目录下的 Debug.xcconfig
和 Release.xcconfig
上进行定制装备。
和 Android 一样, iOS 在编译时会对 --dart-define-from-file
的参数进行转化变成 xcconfig
参数,然后完成 dart 和 iOS 端公用一份变量装备的效果。
最终
能够看到 --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 到稳定分支
期待下个版别 impeller 能给咱们带来更好的体会。