likes
comments
collection
share

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

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

前言

前面一篇文章对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的配置信息已经集成进来了,如何根据配置信息,找到对应需要检测的资源,如果生成所需的代码,就是接下来的执行阶段的事了;

转载自:https://juejin.cn/post/7135039458684403742
评论
请登录