携手创作,一起生长!这是我参与「日新方案 8 月更文挑战」的第4天,点击检查活动概况
前言
这次是对build.yaml
格式做个分析;虽说build_config
自己有对应的文档,但那份文档,怎么说呢,看了有种听君一席话,如听一席话的感觉;看完之后好像懂了,可是写起来完全不知道哪里对应哪里;
这次计划经过源码部分,结合一些详细实战实例,对其中参数怎么装备做一个分析总结;
PS:太长不看背面试题专用陈腔滥调总结版拉最终
PPS:用目录来看会舒适许多;
BuildConfig和build.yaml的对应联系:
关于BuildConfig详细支持的参数,其文档中倒是很明显的表现了出来:
BuildConfig | Value | Default |
---|---|---|
targets | Map<String,BuildTarget> | a single target with the same name as the package |
builders | Map<String,BuilderDefinition> | empty |
post_process_builders | Map<String,PostProcessBuilderDefinition> | empty |
global_options | Map<String,GlobalBuilderOptions> | empty |
additional_public_assets | List | empty |
因而现在得知的情报如下:
build.yaml 支持的参数有:builders
、post_process_builders
、targets
、global_options
、additional_public_assets
;这些是一个build.yaml 榜首级可以装备的参数;如下图所示:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298847-d75e97336af1367.png)
源码中也规则了这些参数:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298851-72cf4a659183464.png)
- targets对应BuildTarget;
- builders对应BuilderDefinition;
- post_process_builders对应PostProcessBuilderDefinition;
- global_options对应GlobalBuilderOptions;
- additional_public_assets是一个List列表;
那么接下来就该看看详细装备内容了;
BuildTarget
参数方面:
Key | Value | Default |
---|---|---|
auto_apply_builders | bool | true |
builders | Map<BuilderKey,TargetBuilderConfig> | empty |
dependencies | List<TargetKey> | all default targets from all dependencies in your pubspec |
sources | InputSet | all defaults sources |
文档中对其解释是这样的:
Dividing a package into Build targets
When a
Builder
should be applied to a subset of files in a package the package can be broken up into multiple ‘targets’. Targets are configured in thetargets
section of thebuild.yaml
. The key for each target makes up the name for that target. Targets can be referred to in'$definingPackageName:$targetname'
. When the target name matches the package name it can also be referred to as just the package name. One target in every packagemustuse the package name so that consumers will use it by default. In thebuild.yaml
file this target can be defined with the key$default
or with the name of the package.Each target may also contain the following keys:
- sources: List of Strings or Map, Optional. The set of files within the package which make up this target. Files are specified using glob syntax. If a List of Strings is used they are considered the ‘include’ globs. If a Map is used can only have the keys
include
andexclude
. Any file which matches any glob ininclude
and no globs inexclude
is considered a source of the target. Wheninclude
is omitted every file is considered a match.- dependencies: List of Strings, Optional. The targets that this target depends on. Strings in the format
'$packageName:$targetName'
to depend on a target within a package or$packageName
to depend on a package’s default target. By default this is all of the package names this package depends on (from thepubspec.yaml
).- builders: Map, Optional. See “configuring builders” below.
不过好像并没说到 auto_apply_builders ?
总结一下的话:
auto_apply_builders
auto_apply_builders 用于buildRunner中BuildPhases
的生成部分,设置为false的话就不会依据当时builder装备去生成BuildPhases
;
换句话说便是要自己装备builder,调用履行builder;
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298855-a06f165d7da5b63.png)
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298859-c5f354e4e9997c9.png)
builders
-
builders 的话,先看其所说的那个;
其对应部分文档:
Configuring
Builder
s applied to your packageEach target can specify a
builders
key which configures the builders which are applied to that target. The value is a Map from builder to configuration for that builder. The key is in the format'$packageName:$builderName'
. The configuration may have the following keys:-
enabled: Boolean, Optional: Whether to apply the builder to this target. Omit this key if you want the default behavior based on the builder’s
auto_apply
configuration. Builders which are manually applied (auto_apply: none
) are only ever used when there is a target specifying the builder withenabled: True
. -
generate_for: List of String or Map, Optional:. The subset of files within the target’s
sources
which should have this Builder applied. Seesources
configuration above for how to configure this. -
options: Map, Optional: A free-form map which will be passed to the
Builder
as aBuilderOptions
when it is constructed. Usage varies depending on the particular builder. Values in this map will override the default provided by builder authors. Values may also be overridden based on the build mode withdev_options
orrelease_options
. -
dev_options: Map, Optional: A free-form map which will be passed to the
Builder
as aBuilderOptions
when it is constructed. Usage varies depending on the particular builder. The values in this map override Builder defaults or non mode-specific options per-key when the build is done in dev mode. -
release_options: Map, Optional: A free-form map which will be passed to the
Builder
as aBuilderOptions
when it is constructed. Usage varies depending on the particular builder. The values in this map override Builder defaults or non mode-specific options when the build is done in release mode.
其对应的两个新增参数类型:
-
enabled: Boolean, Optional: Whether to apply the builder to this target. Omit this key if you want the default behavior based on the builder’s
BuilderKey
BuilderKey
An identifier for a
builder
. A builder has two parts, apackage
and aname
.To construct a key, you join the package and name with a
:
, so for instance thebar
builder in thefoo
package would be referenced like thisfoo:bar
.
但奇怪的是,这部分在我这儿对应的是一个String……不过格式仍是相同的,感觉是我版别的问题;
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298863-589f469efaf4573.png)
对应build.yaml中的这部分内容:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298866-306807208337727.png)
TargetBuilderConfig
TargetBuilderConfig
key | value | default |
---|---|---|
enabled | bool | true |
generate_for | InputSet | ** |
options | BuilderOptions | none |
dev_options | BuilderOptions | none |
release_options | BuilderOptions | none |
enable 的效果正如字面意思,当时TargetBuilderConfig是否启用;假如设置为true,那么后续overrideBuildConfig就会去覆盖builder装备为当时这个TargetBuilderConfig;不然就使用通用的默许装备;
generate_for 又引入了一个叫InputSet
的东西,其实其效果仅仅是一个过滤器:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298870-56dd5dc704f396b.png)
options、dev_options、release_options 这三个都是BuilderOptions,效果也仅仅是供给一下一些装备参数之类的,里边可以放任何自定义的数据:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298874-80c215a142c3832.png)
dependencies
dependencies 字面意思,可用来设定当时BuildTarget的指定依靠;用来后边生成BuildPhases的时候,在项目依靠有向图中先挑选一遍,进而缩小模块巨细规模和数量(感觉是这个意思~~);
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298878-45cddceb5498605.png)
为空的时候会直接以当时package的依靠为默许值;
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298881-9d3aa0e227b39ae.png)
source
source这块便是指输入给builder的部分;同样也是一个InputSet;可以经过这个参数设置给buider开放的输入文件检测规模;
总结
BuildTarget 的效果正如其姓名所述,用于规则builder们的方针、使用规模;
auto_apply_builder用于装备是否主动使用到builder的开关;
builders中重要的部分是TargetBuilderConfig部分,保存了builder的generate_for,自定义参数等东西,供给了生成方针限制和自定义参数的功用;
dependencies 规则了开放给builder的依靠包有哪些;
source 规则了开放给builder的可检测文件的途径有哪些;
BuilderDefinition
key | value | default |
---|---|---|
builder_factories | List | none |
import | String | none |
build_extensions | Map<String, List> | none |
auto_apply | AutoApply | AutoApply.none |
required_inputs | List | none |
runs_before | List<BuilderKey> | none |
applies_builders | List<BuilderKey> | none |
is_optional | bool | false |
build_to | BuildTo | BuildTo.cache |
defaults | TargetBuilderConfigDefaults | none |
万幸新增的东西只要AutoApply、BuildTo和TargetBuilderConfigDefaults三个东西;
再来到到文档部分:
Defining
Builder
s to apply to dependentsIf users of your package need to apply some code generation to their package, then you can define
Builder
s and have those applied to packages with a dependency on yours.The key for a Builder will be normalized so that consumers of the builder can refer to it in
'$definingPackageName:$builderName'
format. If the builder name matches the package name it can also be referred to with just the package name.Exposed
Builder
s are configured in thebuilders
section of thebuild.yaml
. This is a map of builder names to configuration. Each builder config may contain the following keys:
import: Required. The import uri that should be used to import the library containing the
Builder
class. This should always be apackage:
uri.builder_factories: A
List<String>
which contains the names of the top-level methods in the imported library which are a function fitting the typedefBuilder factoryName(BuilderOptions options)
.build_extensions: Required. A map from input extension to the list of output extensions that may be created for that input. This must match the merged
buildExtensions
maps from eachBuilder
inbuilder_factories
.auto_apply: Optional. The packages which should have this builder automatically to applied. Defaults to
'none'
The possibilities are:
"none"
: Never apply this Builder unless it is manually configured"dependents"
: Apply this Builder to the package with a direct dependency on the package exposing the builder."all_packages"
: Apply this Builder to all packages in the transitive dependency graph."root_package"
: Apply this Builder only to the top-level package.required_inputs: Optional, seeadjusting builder ordering
runs_before: Optional, seeadjusting builder ordering
applies_builders: Optional, list of Builder keys. Specifies that other builders should be run on any target which will run this Builder.
is_optional: Optional, boolean. Specifies whether a Builder can be run lazily, such that it won’t execute until one of it’s outputs is requested by a later Builder. This option should be rare. Defaults to
False
.build_to: Optional. The location that generated assets should be output to. The possibilities are:
"source"
: Outputs go to the source tree next to their primary inputs."cache"
: Outputs go to a hidden build cache and won’t be published. The default is “cache”. If a Builder specifies that it outputs to “source” it will never run on any package other than the root – but does not necessarily need to use the “root_package” value for “auto_apply”. If it would otherwise run on a non-root package it will be filtered out.defaults: Optional: Default values to apply when a user does not specify the corresponding key in their
builders
section. May contain the following keys:
- generate_for: A list of globs that this Builder should run on as a subset of the corresponding target, or a map with
include
andexclude
lists of globs.- options: Arbitrary yaml map, provided as the
config
map inBuilderOptions
to theBuilderFactory
for this builder. Individual keys will be overridden by configuration provided in eitherdev_options
orrelease_options
based on the build mode, and then overridden by any user specified configuration.- dev_options: Arbitrary yaml map. Values will replace the defaults from
options
when the build is done in dev mode (the default mode).- release_options: Arbitrary yaml map. Values will replace the defaults from
options
when the build is done in release mode (with--release
).Example
builders
config:builders: my_builder: import: "package:my_package/builder.dart" builder_factories: ["myBuilder"] build_extensions: {".dart": [".my_package.dart"]} auto_apply: dependents defaults: release_options: some_key: "Some value the users will want in release mode"
不得不说,这个builder部分,是挺多参数的~~~~~
builder_factories
builder_factories 是一个必填项,依照我工地英语,翻译了一下其注释,好像是从下面那个import的途径中,获取顶级办法,并将参数转化为builder;
这句话啥意思看不懂没联系,我也没看懂~
找个例子看一下就知道了;
以json_serializable为例,其builder这么写的:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298885-028aa1d841982bd.png)
转化的build.dart 是这样的:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298889-8008281f9c3df3b.png)
而这个_i4.jsonSerializable是个啥东西?
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298893-174718a888f66b3.png)
哦,现在知道了,import是_i4的内容,builder_factories 是要调用的办法名;
build.dart便是经过这两者拿到了自定义的Builder;
import
功用嘛,如上所述;
不过要记得一点,这块的import要以package最初;
build_extensions
必填项,从输入扩展名到输出扩展名的映射。
其实看一下入参也能猜出来;
auto_apply
auto_apply引入了一个新的枚举类:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298897-fad20e8f9a22734.png)
而这个autoApply唯一使用的地方是这儿:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298901-bf46c2aa4ee781d.png)
对应上图的部分,回来的东西是一个PackageFilter
:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298905-8630976950e4953.png)
而这个PackageFilter
的效果是表现在上面那个BuildTarget
的auto_apply_builders
这部分中:
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298908-35759351684bcdc.png)
所以这个装备的效果仍是跟auto_apply_builder相同,用于将依靠包转为builderPhase去履行对应builder的过程中,用于判断是否需求生成对应builderPhase;
所以总结一下的话:
auto_apply 跟BuilderTarget的auto_apply_builder的效果相同,用于挑选是否需求生成builderPhase履行builder;
AutoApply.none,会回来toNoneByDefault的PackageFilter,其不会答应任何PackageNode经过检测,也便是不会生成BuilderPhase,假如没有自己创立、调用的builder,就不要设置此项;
AutoApply.dependents,会回来toDependentsOf的PackageFilter,这个只要自己或者依靠中包含对应package即可;其实便是前面说的,依靠有向图的强连通分量(或者直接说项目依靠模块?)部分;可是父依靠是不判断的,仅仅看自己和子依靠;
AutoApply.allPackages,会回来toAllPackages的PackageFilter,这个直接回来ture,答应任何依靠生成builerPhase;
AutoApply.rootPackage,字面意思,只答应根目录;
required_inputs
用于调整次序,需求比及指定拓宽名类型输出之后才履行;
感觉换个姓名比较好?至少表现一下调整履行次序这种等待联系部分,加个run之类的~~
runs_before
用于调整次序,标明会在指定builder前运行;参数仍是那种package:最初的那种;
applies_builders
标明会运行此builder的builder;参数仍是那种package:最初的那种;
is_optional
标明是否是延迟加载的,其实便是懒汉式这个概念;除非后来的构建器调用readAs*
或canRead
恳求它的输出,不然不会运行。
build_to
虽然build_to 里边又个BuildTo枚举,可是其概念仍是蛮明显的;
build_to 用于生成的源码是放到缓存文件夹中躲藏起来,仍是放到项目中表现出来;
defaults
类型是TargetBuilderConfigDefaults
,其实从姓名也能看出来,其实便是对BuildTarget中的TargetBuilderConfig的兜底装备,设置其默许值而已;
![[Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的? [Flutter] Flutter 的 build 系统(番外篇)--build.yaml里面的参数都是啥?我用这些来干啥的?](https://www.6hu.cc/wp-content/uploads/2022/12/1671298912-fb5e7cc6a4c20b9.png)
总结
BuilderDefinition 是对builder的详细描述部分:
builder_factories 标明会生成builder的办法名;
import 标明要引入的依靠工程;
build_extensions 标明生成映射;
auto_apply 标明的是依据依靠生成builder这个功用的使用规模;
required_inputs和runs_before都是履行混序的调整;
applies_builder 标明会供给给哪些builder用;
is_optional 标明是否是懒汉式
build_to 标明生成的代码是否是躲藏的;
defaults是builder的默许兜底builder装备;
PostProcessBuilderDefinition
PostProcessBuilderDefinition跟BuilderDefinition没有太大区别,唯一不同是builder_factories,由于PostProcess自身便是多个builder,所以只由一个办法供给就行;
结语
总结部分见各章结尾的总结;
现在就该看下Builder该怎么自定义了;以及其自定义才能能到什么程度,跨模块才能有多强;