Flutter 组件化开发实践概述
业务背景:
最近在做一个卡片式的首页模块,这个模块最终会应用到三个app的iOS和Android端,大部分业务相同,但也有一些差异化的东西
所以就考虑到使用跨平台方案去做,考虑到性能和历史原因,最终选用了Flutter
已现存一个Flutter Module项目,但是项目的耦合度很高,开发时也没有做过结构化的设计,直接拿来复用难度还是比较大的
项目结构:
flutter项目工程结构设计为下图:
Native1.png
简述一下:一个flutter module代表一组业务,一个native项目绑定一个flutter module,一个flutter module绑定多个flutter package。这种结构可灵活应对业务任意组合的场景,生成相应的flutter module
所以,这其中涉及到的工作有:
剥离现存flutter module里的基础模块和工具模块,封装成多个package
package设计。例如定义静态接口:如baseUrl、原生bundleId、uid
package制作
package开发时的测试项目配置或者单元测试
我们在组件化过程遇到的几个问题
一、package代码放在哪?
pub官方 发布流程
git仓库:上传package到git仓库,在业务pubspec.yaml中如下配置,即可简单依赖你的package,其中ref可以是tag、branch
your_package: git: url: http://xxxx/xxx/your_package ref: 0.0.1 path: your_package
自建服务器 发布流程
二、package开发时怎么调试?
1. 使用example工程调试
使用
flutter create example
命令创建示例工程在example工程的pubspec.yaml文件中引入package相对路径
dependencies: flutter: sdk: flutter your_package: path: ../
在.vscode/launch.json中配置example调试入口
{ "version": "0.2.0", "configurations": [ { "name": "your_package", "cwd": "your_package", "request": "launch", "type": "dart" }, { "name": "debug_example", "program": "your_package/example/lib/main.dart", "request": "launch", "type": "dart", "flutterMode": "debug" }, ]}
2. 单元测试/小部件测试/集成测试
官方文档
在
widget_test.dart
文件下的main函数中书写测试代码
void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); // Tap the '+' icon and trigger a frame. await tester.tap(find.byIcon(Icons.add)); await tester.pump(); // Verify that our counter has incremented. expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); });}
三、加载package磁盘资源的正确姿势?
注意
:在业务项目或者package项目获取package资源,都需要指明绝对路径
一般资源
// 图片Image.asset("packages/your_package/images/your_image.png")// jsonawait rootBundle.loadString('packages/your_package/jsons/your_json.json');// 其他资源依然要'packages/your_package/jsons/your_json.json'传入相关api的路径形参
图片资源
注意
:assetName可使用相对路径,但要指明package
Image(image: AssetImage("images/your_image.png", package: 'your_package'))
四、package和外界通信的方式?
建议在package新建dart抽象类,在外界实例化抽象类,把实例作为代理传入package模块
作者:mtko
链接:https://www.jianshu.com/p/55824588f99f