flutter编译流程修改
# flutter条件编译以及shell脚本/dart脚本
# 问题
- 如何实现条件编译?
- 能在yaml里写if-else条件判断吗?
- 多package的工程,怎么做到package发布到pub的功能和本地path依赖的形式同时存在?
- yaml里能自定义配置吗?
- dart代码里怎么读取自定义配置?
- 有类似spring boot那样的多个yaml,覆盖配置吗?
# 1 多package的工程,怎么做到package发布到pub的功能和本地path依赖的形式同时存在?
类似gradle工程发布到jitpack时,自动将本地依赖替换为远程依赖
正常代码里是这样:
dependencies:
webview_flutter: ^3.0.4
pkg_base_lib:
path: ../pkg_base_lib
2
3
4
希望发布时,运行 dart pub publish --dry-run
时,pkg_base_lib的path依赖自动替换为当前指定的某个版本号的依赖
一般来说,只能自己写个shell脚本/dart脚本,在运行dart pub publish前调用,
将yaml文件拷贝一份,将所有package里的path替换为远程依赖,
然后运行publish,
运行完成后,再将文件拷贝回来.
# 2 yaml配置读取/编辑工具
https://pub.dev/packages/yaml_config_reader
只能读取assets下的文件,不能读pubspec.yaml
https://pub.dev/packages/yaml 官方yaml读工具,推荐
写yaml的工具: map转yaml: yaml_writer: ^1.0.2
https://pub.dev/packages/process_run dart的命令行调用工具--> 无法接受用户输入. 那么使用dart pub publish --force可以不需要确认,无需交互
https://pub.dev/packages/dcli
# 3 flutter命令行支持的一些条件编译
https://blog.deskangel.com/2021/06/16/flutter-conditional-compiling/
Flutter下的实现原理主要是它可以通过编译参数指定不同的入口文件:
flutter build apk --help
....
-t, --target=<path> The main entry-point file of the application, as run on the
device.
If the "--target" option is omitted, but a file name is provided
on the command line, then that is used instead.
(defaults to "lib/main.dart")
2
3
4
5
6
7
另外,它也支持指定flavor,可以透传到gradle:
--flavor Build a custom app flavor as defined by platform-specific build
setup.
2
# 编译脚本
由于没有很好的办法对pubspec.yaml
中的packages进行“条件控制”,比如没有找到办法创建诸如google_dependencies
这样的入口,所以只能通过命令来进行控制:
flutter pub remove --offline in_app_purchase
flutter build appbundle --release --flavor=huawei -t lib/main.huawei.dart
flutter pub add --offline in_app_purchase
2
3
针对huawei的编译,先移除google的in_app_purchase
包,然后通过--flavor
指定风味,通过-t
指定flutter的main
文件,编译完成后再把包加回去。
# 4 命令行指定参数,dart代码内获取
从 Flutter v1.17
开始,Flutter 命令工具增加了自定义参数的功能 --dart-define
,我们可以用这个命令参数在打包或运行 App 时设置参数即可。
首先确定
Flutter
版本,我的版本是v1.22.6
flutter run --dart-define=APP_CHANNEL=ZeroFlutter
当然你可以传递多组参数
flutter run --dart-define=APP_CHANNEL=ZeroFlutter --dart-define=OTHER_VAR=Dart
在 Dart 代码中你需要这样写,一定是和命令参数是对应的
// main.dart
class EnvironmentConfig {
static const APP_CHANNEL = String.fromEnvironment('APP_CHANNEL');
static const OTHER_VAR = String.fromEnvironment('OTHER_VAR');
}
2
3
4
5
# 5 dart代码内部用到一些平台特有api导致编译失败时:
https://github.com/fengdeyingzi/definetool
# 1.在代码中加入宏注释
// #ifdef WINDOWS
print("hello windows");
// #endif
// #ifdef WEB
print("hello web");
// #endif
2
3
4
5
6
7
# 2.在代码所在目录运行findtool工具,并定义宏:WINDOWS
这个命令可直接在本项目上操作来查看效果
definetool -define WINDOWS
在编译时若没有此宏,会将define与endif之间的内容进行/**/注释,若有宏,则进行解除注释。
宏内定义的内容不要使用多行注释