wuba / Fair

A Flutter package used to update widget tree dynamically. Fair提供一整套Flutter动态化解决方案
https://fair.58.com
BSD 3-Clause "New" or "Revised" License
2.61k stars 310 forks source link

flutter pub run build_runner build 第三方框架转不出来 #28

Open shenLaiMango opened 3 years ago

shenLaiMango commented 3 years ago

问题

引用了第三方框架:

框架1

common_utils: ^1.2.1

图片加载 框架2

cached_network_image: ^2.2.0+1

Text扩展组件 框架3

extended_text: ^0.6.6

在mian如此声明: @FairBinding( packages: [ 'package:cached_network_image/cached_network_image.dart', 'package:common_utils/common_utils.dart', 'package:extended_text/extended_text.dart' ])

但是转不出来 image 【备注:自定义的框架可以转出来】 环境信息 flutter sdk 1.17.3

提供Fair版本号

添加 Fair 依赖

fair: ^0.2.0

dev_dependencies: flutter_test: sdk: flutter

添加编译器依赖

build_runner: ^1.4.0 fair_compiler: ^0.2.0

Switch to another stable flutter version

dependency_overrides: fair_version: git: url: https://github.com/wuba/fair.git ref: main path: fair_version/flutter_1_17_3

yancechen commented 3 years ago

1.common_utils 插件无法转换的原因

@FairBinding 是用来为 布局 生成组件映射关系的,而 common_utils 这个库本身不是 UI 相关的库,只是一个工具库,common_utils.dart 文件里写的也不是布局相关的代码,而是对外暴露的 API:

library common_utils;

export 'src/date_util.dart';
export 'src/encrypt_util.dart';
export 'src/json_util.dart';
export 'src/log_util.dart';
export 'src/money_util.dart';
export 'src/num_util.dart';
export 'src/object_util.dart';
export 'src/regex_util.dart';
export 'src/text_util.dart';
export 'src/timeline_util.dart';
export 'src/timer_util.dart';

2.cached_network_image 插件无法转换的原因

查看 cached_network_image 库的源码我们发现,他的主要实现代码放在了 src 的目录下,在 cached_network_image.dart 里面并不是布局相关代码,而是对外暴露的 API,因此通过下面的方式无法生成组件映射关系:

@FairBinding(packages: ['package:cached_network_image/cached_network_image.dart'])

正确的引用方式为:

@FairBinding(packages: ['package:cached_network_image/src/cached_image_widget.dart'])

我们会在后续的版本中,考虑兼容这种情况。

我们以 cached_network_image: ^2.5.0 这个版本为例:

运行结果:

// Generated by Fair on 2021-05-31 16:09:54.002728.
import 'package:cached_network_image/src/cached_image_widget.dart';

import 'package:flutter/material.dart';
import 'package:fair/fair.dart';
import 'package:fair_version/fair_version.dart';

class AppGeneratedModule extends GeneratedModule {
  @override
  Map<String, dynamic> components() {
    return {
      'CachedNetworkImage': (props) => CachedNetworkImage(
            key: props['key'],
            imageUrl: props['imageUrl'],
            httpHeaders: props['httpHeaders'],
            imageBuilder: props['imageBuilder'],
            placeholder: props['placeholder'],
            progressIndicatorBuilder: props['progressIndicatorBuilder'],
            errorWidget: props['errorWidget'],
            fadeOutDuration:
                props['fadeOutDuration'] ?? const Duration(milliseconds: 1000),
            fadeOutCurve: props['fadeOutCurve'] ?? Curves.easeOut,
            fadeInDuration:
                props['fadeInDuration'] ?? const Duration(milliseconds: 500),
            fadeInCurve: props['fadeInCurve'] ?? Curves.easeIn,
            width: props['width']?.toDouble(),
            height: props['height']?.toDouble(),
            fit: props['fit'],
            alignment: props['alignment'] ?? Alignment.center,
            repeat: props['repeat'] ?? ImageRepeat.noRepeat,
            matchTextDirection: props['matchTextDirection'] ?? false,
            cacheManager: props['cacheManager'],
            useOldImageOnUrlChange: props['useOldImageOnUrlChange'] ?? false,
            color: props['color'],
            filterQuality: props['filterQuality'] ?? FilterQuality.low,
            colorBlendMode: props['colorBlendMode'],
            placeholderFadeInDuration: props['placeholderFadeInDuration'],
            memCacheWidth: props['memCacheWidth'],
            memCacheHeight: props['memCacheHeight'],
            cacheKey: props['cacheKey'],
            maxWidthDiskCache: props['maxWidthDiskCache'],
            maxHeightDiskCache: props['maxHeightDiskCache'],
            imageRenderMethodForWeb: props['imageRenderMethodForWeb'],
          ),
    };
  }

  @override
  Map<String, bool> mapping() {
    return const {
      'CachedNetworkImage': true,
      'Test': true,
    };
  }
}

demo 效果:

Screenshot_20210601_141718_com.example.fair_issue.jpg

3.extended_text 插件无法转换的原因

原因和 cached_network_image 类似,他们的实现代码都是在 src 目录下,extended_text.dart 里面也是写的对外暴露的 API,而不是具体的布局代码。

想要为某个组件生成映射关系,必须去 src 目录下找到对应得 dart 文件。

extended_text: ^6.0.0 这个版本为例,我们想为 ExtendedRichText 生成映射关系,它的路径在 src/extended_rich_text.dart,那么使用 FairBinding 时,需要把这个路径代上:

@FairBinding(packages: ['package:extended_text/src/extended_rich_text.dart'])

运行结果:

'ExtendedRichText': (props) => ExtendedRichText(
            key: props['key'],
            text: props['text'],
            textAlign: props['textAlign'] ?? TextAlign.start,
            textDirection: props['textDirection'],
            softWrap: props['softWrap'] ?? true,
            overflow: props['overflow'] ?? TextOverflow.clip,
            textScaleFactor: props['textScaleFactor']?.toDouble() ?? 1.0,
            maxLines: props['maxLines'],
            locale: props['locale'],
            onSelectionChanged: props['onSelectionChanged'],
            strutStyle: props['strutStyle'],
            textWidthBasis: props['textWidthBasis'] ?? TextWidthBasis.parent,
            selection: props['selection'],
            selectionColor: props['selectionColor'],
            startHandleLayerLink: props['startHandleLayerLink'],
            endHandleLayerLink: props['endHandleLayerLink'],
            textHeightBehavior: props['textHeightBehavior'],
            selectionHeightStyle:
                props['selectionHeightStyle'] ?? BoxHeightStyle.tight,
            selectionWidthStyle:
                props['selectionWidthStyle'] ?? BoxWidthStyle.tight,
            overflowWidget: props['overflowWidget'],
            textSelectionDelegate: props['textSelectionDelegate'],
            hasFocus: props['hasFocus'],
          ),

备注一下我的运行环境:

Flutter SDK:1.22.6 Dart SDK:2.10.5

fair: ^0.3.0 build_runner: ^1.4.0 fair_compiler: ^0.3.0

cuocuo commented 2 years ago

https://github.com/wuba/fair/pull/151 这个pullrequest应该修复这个问题了,自测可以@FairBinding(packages: ['package:cached_network_image/cached_network_image.dart'])这样引用。 麻烦review一下。 @yancechen