Flutter build-runner工具简单使用

build_runner 

提供了一些用于生成文件的通用命令,这些命令中有的可以用于测试生成的文件,有的可以用于对外提供这些生成的文件以及它们的源代码。

如果你开发的是 Web : 你可以使用 webdev 工具替代 build_runner 以构建和提供 Web 应用。

build Summary

Get Start

pubspec.yaml添加依赖

dependencies:
  flutter:
    sdk: flutter
  build_runner: any

build.yaml添加build配置 具体配置参考build_config

builders:
  my_builder:
    import: "package:flutter_test_1/test_builder.dart"
    builder_factories: ["testBuilder"]
    build_extensions: {".dart": [".test.dart"]}
    auto_apply: root_package

builder完成需要的具体功能

import 'dart:async';

import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';

Builder testBuilder(BuilderOptions options) {
  return TestBuilder();
}

class TestBuilder extends Builder {
  @override
  Future build(BuildStep buildStep) async {
//    print('${buildStep.inputLibrary}');
    await printAllElements(buildStep);
  }

  ClassElement findType(LibraryElement element, String name) {
    final type = element.exportNamespace.get(name);
    return type is ClassElement ? type : null;
  }

  /// All of the declarations in this library.
  Future printAllElements(BuildStep buildStep) async {
    final element = await buildStep.inputLibrary;
    print('**************************');
    /// element数据
    print(element.displayName);
    for (var cu in element.units) {
//      final buffer = StringBuffer();
      final types = cu.types;

      for (var type in types) {
//        buffer.write('${type.displayName}: superTypes-${type.allSupertypes}, fields-${type.fields}\n');
//        buffer.write('${type.displayName}: fields-${type.fields}, allSupertypes-${type.allSupertypes}, accessors-${type.accessors}, constructors-${type.constructors}, declaration-${type.declaration}, documentationComment-${type.documentationComment}, enclosingElement-${type.enclosingElement}\n');
      }
//      print('${cu.displayName}: ${cu.accessors}');
//      print(' ${cu.enums}');
//      print(' ${cu.functionTypeAliases}');
//      print(' ${cu.functions}');
//      print(' ${cu.mixins}');
//      print(' ${cu.topLevelVariables}');
//      print('${buffer.toString()}');
    }
  }

  @override
  Map<String, List<String>> buildExtensions = {'.dart': ['.test.dart']};
}

Builder BuildStep源码

/// The basic builder class, used to build new files from existing ones.
abstract class Builder {
  /// Generates the outputs for a given [BuildStep].
  FutureOr<void> build(BuildStep buildStep);

  /// 设置输入输出文件扩展名
  Map<String, List<String>> get buildExtensions;
}

/// A single step in a build process.
///
/// This represents a single [inputId], logic around resolving as a library,
/// and the ability to read and write assets as allowed by the underlying build
/// system.
/// 一个文件的构建信息(一个dart文件对应一个library)
abstract class BuildStep implements AssetReader, AssetWriter {
  /// The primary for this build step.
  AssetId get inputId;

  /// Resolved library defined by [inputId].
  ///
  /// Throws [NonLibraryAssetException] if [inputId] is not a Dart library file.
  Future<LibraryElement> get inputLibrary;

  /// Gets an instance provided by [resource] which is guaranteed to be unique
  /// within a single build, and may be reused across build steps within a
  /// build if the implementation allows.
  ///
  /// It is also guaranteed that [resource] will be disposed before the next
  /// build starts (and the dispose callback will be invoked if provided).
  Future<T> fetchResource<T>(Resource<T> resource);
    
  /// Writes [bytes] to a binary file located at [id].
  ///
  /// Returns a [Future] that completes after writing the asset out.
  ///
  /// * Throws a `PackageNotFoundException` if `id.package` is not found.
  /// * Throws an `InvalidOutputException` if the output was not valid.
  ///
  /// **NOTE**: Most `Builder` implementations should not need to `await` this
  /// Future since the runner will be responsible for waiting until all outputs
  /// are written.
  @override
  Future<void> writeAsBytes(AssetId id, FutureOr<List<int>> bytes);

  /// Writes [contents] to a text file located at [id] with [encoding].
  ///
  /// Returns a [Future] that completes after writing the asset out.
  ///
  /// * Throws a `PackageNotFoundException` if `id.package` is not found.
  /// * Throws an `InvalidOutputException` if the output was not valid.
  ///
  /// **NOTE**: Most `Builder` implementations should not need to `await` this
  /// Future since the runner will be responsible for waiting until all outputs
  /// are written.
  @override
  Future<void> writeAsString(AssetId id, FutureOr<String> contents,
      {Encoding encoding = utf8});

  /// A [Resolver] for [inputId].
  Resolver get resolver;

  /// Tracks performance of [action] separately.
  ///
  /// If performance tracking is enabled, tracks [action] as separate stage
  /// identified by [label]. Otherwise just runs [action].
  ///
  /// You can specify [action] as [isExternal] (waiting for some external
  /// resource like network, process or file IO). In that case [action] will
  /// be tracked as single time slice from the beginning of the stage till
  /// completion of Future returned by [action].
  ///
  /// Otherwise all separate time slices of asynchronous execution will be
  /// tracked, but waiting for external resources will be a gap.
  ///
  /// Returns value returned by [action].
  /// [action] can be async function returning [Future].
  T trackStage<T>(String label, T Function() action, {bool isExternal = false});

  /// Indicates that [ids] were read but their content has no impact on the
  /// outputs of this step.
  ///
  /// **WARNING**: Using this introduces serious risk of non-hermetic builds.
  ///
  /// If these files change or become unreadable on the next build this build
  /// step may not run.
  ///
  /// **Note**: This is not guaranteed to have any effect and it should be
  /// assumed to be a no-op by default. Implementations must explicitly
  /// choose to support this feature.
  void reportUnusedAssets(Iterable<AssetId> ids);
}

import 'package:build/build.dart';

/// A really simple [Builder], it just makes copies of .txt files!
class CopyBuilder implements Builder {
  @override
  final buildExtensions = const {
    '.txt': ['.txt.copy']
  };

  @override
  Future<void> build(BuildStep buildStep) async {
    // Each `buildStep` has a single input.
    var inputId = buildStep.inputId;

    // Create a new target `AssetId` based on the old one.
    var copy = inputId.addExtension('.copy');
    var contents = await buildStep.readAsString(inputId);

    // Write out the new asset.
    await buildStep.writeAsString(copy, contents);
  }
}
import 'package:build/build.dart';

class ResolvingCopyBuilder implements Builder {
  // Take a `.dart` file as input so that the Resolver has code to resolve
  @override
  final buildExtensions = const {
    '.dart': ['.dart.copy']
  };

  @override
  Future<void> build(BuildStep buildStep) async {
    // Get the `LibraryElement` for the primary input.
    var entryLib = await buildStep.inputLibrary;
    // Resolves all libraries reachable from the primary input.
    var resolver = buildStep.resolver;
    // Get a `LibraryElement` for another asset.
    var libFromAsset = await resolver.libraryFor(
        AssetId.resolve('some_import.dart', from: buildStep.inputId));
    // Or get a `LibraryElement` by name.
    var libByName = await resolver.findLibraryByName('my.library');
  }
}

参考

https://juejin.im/post/5da5af226fb9a04e046bcbaa

 

结论

build-runner是纵向的,横向package扫描不到;能够扫描出成员变量、构造函数、所有父类、注释等

寻找横向扫描方法

探究color的类型被扫描成了dynamic的原因

 

使用Analyzer,可以直接对整个项目进行扫描,针对每个dart文件扫描出的语法树进行分析。

使用build_runner,能够扫描出每个dart文件中类成员变量、构造函数、所有父类、注释等。

可以结合使用,build_runner用来获取父类信息。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 我不是很清楚Flutter打包android和ios的具体流程,但是根据我从网上查询的信息,可以通过使用Flutter CLI来打包Android和iOS应用程序,并使用Flutter提供的构建工具来生成最终的应用程序文件。 ### 回答2: Flutter是一种开源的跨平台移动应用开发框架,它可以同时打包Android和iOS两个平台的应用。下面将分别介绍Flutter打包Android和iOS的步骤。 Flutter打包Android应用的步骤如下: 1. 首先,我们需要在Flutter项目的根目录下执行命令`flutter build apk`,该命令会利用Flutter的打包工具将代码编译成Android应用可执行文件。 2. 打包完成后,在项目的`build/app/outputs/apk/release`路径下会生成一个名为`app.apk`的文件,这就是我们需要的Android安装包。 3. 如果需要对该安装包进行签名,可以使用Java开发工具包(JDK)自带的`keytool`生成一个密钥库文件(keystore),然后利用Android Studio自带的`apksigner`工具对APK进行签名。 4. 最后,我们可以将签名后的APK安装包通过各种方式进行发布和安装。 Flutter打包iOS应用的步骤如下: 1. 在Flutter项目的根目录下执行命令`flutter build ios`,该命令会利用Flutter的打包工具将代码编译成iOS应用可执行文件。 2. 打包完成后,在项目的`build/ios/iphoneos`路径下会生成一个名为`Runner.app`的文件,这就是我们需要的iOS应用。 3. 接下来,我们需要在Xcode中打开`Runner.xcworkspace`文件,并配置开发者账号和相关证书。 4. 在Xcode中选择设备或模拟器,然后点击菜单栏的`Product -> Archive`选项,Xcode将会对应用进行打包。 5. 打包完成后,在`Xcode -> Window -> Organizer`界面中可以找到App Archives,我们可以选择对应的应用版本进行导出或发布。 总结来说,Flutter通过使用自身的打包工具,可以快速便捷地打包Android和iOS应用,对于开发者来说非常方便。同时,开发者还可以根据需要对打包后的应用进行签名或发布。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值