美文网首页
Flutter 组件化开发实践概述

Flutter 组件化开发实践概述

作者: mtko | 来源:发表于2021-02-09 21:01 被阅读0次

    业务背景:

    最近在做一个卡片式的首页模块,这个模块最终会应用到三个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")
    
    // json
    await 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模块

    相关文章

      网友评论

          本文标题:Flutter 组件化开发实践概述

          本文链接:https://www.haomeiwen.com/subject/qmwnnktx.html