likes
comments
collection
share

[Flutter] Flutter 的 build 系统(三)--BuildRunner

作者站长头像
站长
· 阅读数 7

前言

之前的文章对build.dart 如何生成的做了一个简单分析,现在build.yaml配置参数已经通过build.dart 引入到build体系中了,接下来就该根据参数执行builder了;

在第一篇文章中简单概括了build.dart 的执行流程,最终是由build.dart 会执行BuildRunner去执行所有builder并返回结果;那么现在就该看下BuildRunner到底做了什么;

BuildRunner

[Flutter] Flutter 的 build 系统(三)--BuildRunner

BuilderOption

首先是配置参数部分,在这里首先构建了BuilderOption,其所需的参数中除了一些bool开关之类的简单配置外,就只有三个部分:packageGraphoveridBuildConfigresolvers

其中packageGraph在前面文章中经常见了,根据pubspec.yaml而生成的依赖有向图;

overidBuildConfig也是打过招呼的部分,是根据build.yaml生成的BuildConfigMap;

resolvers这个还没介绍过,看注释,其作用是生成BuildStep,在这里先跳过,这个BuildStep里面又搞出好几个新东西,后面一起看;

[Flutter] Flutter 的 build 系统(三)--BuildRunner

BuilderOption 的创建是通过其create方法,其方法中会先创建TargetGraph,之后给resolver分配个兜底值(AnalyzerResolvers),最后组合起来;

而这个TargetGraphPackageGraph的区别是,PackageGraph 是根据pubspec.yaml生成的;而TargetGraph是在PackageGraph基础上,使用overridBuildConfig覆盖之后生成的;这也是其forPackageGraph方法中需要的两个参数;

[Flutter] Flutter 的 build 系统(三)--BuildRunner

defaultRootPackageSources是默认的source列表;

[Flutter] Flutter 的 build 系统(三)--BuildRunner

对应BuildConfig->BuildTarget->InputSet的include变量;

这个BuildConfig里面一大堆参数,最后在整个番外篇,整理下具体跟build.yaml中哪部分对应,起什么作用?

剩下的两个,好像是模块合规性检测用的,如果有package不包含填入路径的东西,那么就提一下警告;

BuildRunner

BuildOption完成后,就是BuildRunner的创建和执行;

创建环节

createBuildPhases

BuildRunner的create方法,最终走到的部分是BuildImpl.create

[Flutter] Flutter 的 build 系统(三)--BuildRunner

首先,其中的入参前面都已经提及过了;可以直接往下走;

接下来通过_createBuildPhasesWithinCycle创建了一个名为BuildPhases的东西;BuildPhases是一个用来表述当前任务步骤的类,用来承载具体要执行的builder和其最终配置,最后以一个列表的形式组合起来;

其分为InBuildPhase(只执行单个builder的步骤)和PostBuildPhase(可以执行复数个builder的步骤),其实分别代表的就是在build.yaml中的builderpost_process_builders这两部分;

[Flutter] Flutter 的 build 系统(三)--BuildRunner

其中存放的参数为:

[Flutter] Flutter 的 build 系统(三)--BuildRunner

  • builder:自然就是构造器;
  • builderLabel:构造器label,不用太在意;
  • builderOptions:前面出现过;
  • generateFor:对应build.yaml中的generate_for部分;
  • package:包名;
  • targetSources:对应build.yaml中的source部分;

其生成也是在build.dart 中就区分好了,比如说这样:

[Flutter] Flutter 的 build 系统(三)--BuildRunner

如果在build.yaml中声明了builders,那么apply方法就会通过BuilderApplication.forBuilder生成InBuildPhase

[Flutter] Flutter 的 build 系统(三)--BuildRunner

如果在build.yaml中声明了post_process_builders,那么applyPostProcess就会通过BuilderApplication.forPostProcessBuilder生成PostBuildPhase

[Flutter] Flutter 的 build 系统(三)--BuildRunner

prepareWorkspace

这步的作用正如字面意思。对应代码是:

var buildDefinition = await BuildDefinition.prepareWorkspace(
    environment, options, buildPhases);

这一步会生成一个名为BuildDefinition的东西;其成员变量如下:

[Flutter] Flutter 的 build 系统(三)--BuildRunner

需要注意的参数中多了一个AssetGraph的东西;按照其注释的意思,应该是在build过程中用到的文件资源的依赖有向图;在这里做个序列化并缓存起来;

其位置是这个:

[Flutter] Flutter 的 build 系统(三)--BuildRunner

对应部分是这些:

[Flutter] Flutter 的 build 系统(三)--BuildRunner

再之后就是检查有没有拿到这个缓存文件,拿到的话,通过AssetTracker追踪并检查一次更新,没拿到就创建并缓存起来。最后把这些信息,结合上之前的环境部分提供的reader和writer,组合起来就是BuildDefinition

SingleStepReader

这个环节,按照其注释,好像也仅仅是提供日志和追踪的东西:

[Flutter] Flutter 的 build 系统(三)--BuildRunner

FinalizedReader

这个环节好像也仅仅是忽略了删除文件,跟普通的AssetReader并无太大区别

[Flutter] Flutter 的 build 系统(三)--BuildRunner

执行环节

在创建完成之后,就轮到了调用run去真正执行的环节;

[Flutter] Flutter 的 build 系统(三)--BuildRunner

其实这步所做的事,在第一篇中已经概括了,说白了就是调用_safeBuild开个Zone去获取最终的执行结果,然后该缓存缓存,该收尾收尾~~~

结语

至此,build系统的基本流程就大体分析完了

其实难点还是搞了一大堆名字很相似的新名词…………现在感觉基本比着 build_config 来过一遍效果会好很多;