携手创作,共同生长!这是我参加「日新计划 8 月更文应战」的第2天,点击查看活动详情

前言

前面一篇文章对Flutter的build系统做了一次流程的开始整理;可是详细的细节部分还未深化;现在就从头深化了解一下细节部分;

这次就对第一步中生成的build.dart 脚本文件进行一下整理剖析;

build.dart 脚本文件的内容

首先简略温习一下build.dart 脚本文件相关的部分的内容:

  • build.dart 文件的位置是:.dart_tool/build/entrypoint/build.dart
  • build.dart 内容生成的指令是:build_script_generate.dart
  • 一般情况下,生成 build.dart 的脚本文件是:bootstrap.dart
  • build.dart 所做的事体现在内核编译部分;会以build.dart.dill文件的方式去履行,经过层层封装转发,终究来到src/generate/build.dart 文件的build办法中中去履行;

那么接下来就从内容和履行两个方面剖析一下 build.dart 的详细生成步骤,及其数据来历等细节部分;

build.dart 的生成

build.dart 的main办法部分现已在内核编译部分简略剖析了一遍。不过对其间的_builders列表内容来自哪里并未做剖析,要想剖析这块的东西,就要来到build_script_generate.dart 文件中:

[Flutter] Flutter 的 build 系统(二)--build.dart 的生成过程解析

简略概括一下:

  1. 生成构建信息(BuildScriptInfo);
  2. 依据构建信息中的内容构建引用信息等部分(Library);终究生成内容(library.accept(emitter)),调用DartFormatter.format格式化代码;

BuildScriptInfo

BuildScriptInfo的效果正如其字面意思的那样,只是供给了BuildScript所需的info信息:

[Flutter] Flutter 的 build 系统(二)--build.dart 的生成过程解析

其内容也不多,一个是用来存放Builder的List,一个是是否支撑空安全的值;

来到BuildSriptInfo 生成的部分便是下面这句:

final info = await findBuildScriptOptions();

findBuildScriptOptions办法首要做的事也按照这几步来走:

[Flutter] Flutter 的 build 系统(二)--build.dart 的生成过程解析

PS:图中的那个强关系节点,其实应该叫强连通重量,在这里是经过Tarjan算法找到依靠有向图的强连通重量;感觉说白了便是划分模块的意思;

[Flutter] Flutter 的 build 系统(二)--build.dart 的生成过程解析

而其间就出现了build系统中的build_config;在build.yaml中声明的装备信息,也是在这里引入了进来;

接下来便是一些合规性检查,终究把声明的builder都合并过来,检查一下是不是空安全的:

[Flutter] Flutter 的 build 系统(二)--build.dart 的生成过程解析

至此,buildScriptInfo就组成出来了;咱们写在build.yaml中的builder现已带入到其间了;

代码生成

先是Library其实也是代码生成的那部分,触及代码如下:

final library = Library((b) => b.body.addAll([
      literalList(
              builders,
              refer('BuilderApplication',
                  'package:build_runner_core/build_runner_core.dart'))
          .assignFinal('_builders')
          .statement,
      _main()
    ]));

其间的literalList、refer、assignFinal、statement之类的东西,其实都是core_builder中的部分,属于生成代码的辅佐部分;

比如说assignFinal(‘_builders’) ,声明了办法名,并贴上final。refer这块规则了格式类型;那个_main办法也是相同,规则了代码生成格式罢了;

不过这段生成的部分,只是对应build.dart中的 final _builders = <_i1.BuilderApplication>[]部分;像import之类的还需求后面看一下;

[Flutter] Flutter 的 build 系统(二)--build.dart 的生成过程解析

接下来相关部分便是这块:

[Flutter] Flutter 的 build 系统(二)--build.dart 的生成过程解析

在这里新建了一个StringBuffer用来填充内容;之后就调用了library.accept;

精简的话,终究其实便是这两处:

[Flutter] Flutter 的 build 系统(二)--build.dart 的生成过程解析

directive.accept办法其实便是调用了一下visitDirective办法;

[Flutter] Flutter 的 build 系统(二)--build.dart 的生成过程解析

所以说终究结果便是visitDirective+body两部分结合;

body其实便是前面创建Library中提到的部分;visitDirective则是所需求的import这帮:

[Flutter] Flutter 的 build 系统(二)--build.dart 的生成过程解析

这样生成build.dart 脚本文件所需的东西就集全了;

build.dart 的效果;

其效果也在上篇文章中简略总结了下:

其实便是生成内核文件,将经过build_config解析出来的装备信息和项目环境独自整合为一个独立的指令;然后发送给isolate去真实履行builder中的内容;

结语

现在过了一遍build.dart 的生成过程,也看到build_config 的效果;

那么现在已知build.yaml的装备信息现已集成进来了,如何依据装备信息,找到对应需求检测的资源,如果生成所需的代码,便是接下来的履行阶段的事了;