如何编写Builder(Transformer)并在build_runner中使用及Angular发布构建疑问
嘿,针对你在Angular Dart发布构建中遇到的Builder相关问题,我来逐一拆解解答,结合你使用的Angular 5.0.0-alpha+8和Dart 2.0.0-dev.36.0环境来说明:
Builder vs Pub Transformer:核心差异
首先得明确,Pub Transformer是旧版pub构建系统(pub build/pub serve)的产物,而Builder是新的build_runner生态的核心组件,两者的差异主要体现在这几点:
- 灵活性与集成度:Transformer只能做简单的文件输入输出转换,依赖线性的处理流程;Builder支持增量构建、并行执行,能和Angular模板编译、dart2js编译等核心构建步骤深度集成,处理复杂的依赖关系。
- 生命周期管理:Builder有更清晰的构建生命周期,能通过
buildStep访问构建上下文,获取依赖文件状态、缓存等;Transformer没有这些能力,只能被动接收文件流。 - 生态兼容性:Angular 5+已经完全基于
build_runner构建,Transformer基本被弃用,官方不再维护相关文档,所以优先用Builder是正确的选择。
在哪里调用你的Builder
Builder是通过构建配置文件(build.yaml或环境特定的build.release.yaml)来注册和调用的,不需要手动在代码里调用:
- 首先确保你的Builder已经在项目的
pubspec.yaml中添加了依赖(如果是第三方Builder),或者如果你是自己编写的Builder,要在当前包的pubspec.yaml中声明builders节点注册它。 - 然后在
build.release.yaml的targets.$default.builders下添加你的Builder配置,这就是调用它的方式——build_runner会在执行构建时自动加载并运行所有配置的Builder。
如何控制构建顺序
build_runner会自动根据文件依赖关系排序Builder的执行顺序,但如果你有明确的顺序需求,可以通过两种方式控制:
- Builder层面的依赖声明:在编写Builder类时,通过
buildExtensions指定输入输出的文件扩展名,build_runner会自动识别依赖;或者在Builder的build方法中使用await buildStep.canRead(inputId)等待依赖文件生成后再执行。 - 配置层面的依赖指定:在
build.release.yaml的Builder配置中添加depends_on字段,指定你的Builder需要依赖的其他Builder。比如如果你的Builder需要在dart2js编译前运行,可以这样配置:
这样build_runner会确保call_my_builder: depends_on: - build_web_compilers|entrypointbuild_web_compilers|entrypoint执行完成后,再运行你的Builder。
你的
build.release.yaml配置是否正确? 看你给出的配置,有几处需要修正:
- Builder配置格式错误:
call_my_builder不能直接作为列表项,必须是键值对格式。如果是第三方Builder,要写成包名|Builder名: {};如果是当前包内的自定义Builder,写成:Builder名: {}。比如:builders: :my_resource_transformer: {} # 假设是当前包的自定义Builder build_web_compilers|entrypoint: # ... 你的dart2js配置 - 可选:添加
generate_for和options:如果你的Builder只需要处理特定文件,或者需要传入自定义参数,可以补充配置::my_resource_transformer: generate_for: - web/**.svg # 指定只处理web下的svg资源 options: output_format: webp # 自定义转换选项 - 其他部分是正确的:
sources包含了lib和web的所有文件,build_web_compilers|entrypoint的dart2js参数配置符合release构建的需求(压缩、快速启动等)。
最后补充下编写自定义Builder的基本流程,供你参考:
- 创建一个dart包(可以是项目内的子包,或者单独的包)。
- 在
pubspec.yaml中添加build、build_runner作为依赖。 - 编写
class MyBuilder implements Builder,重写buildExtensions(定义输入输出文件匹配规则)和build方法(实现资源转换逻辑)。 - 在
pubspec.yaml的builders节点注册你的Builder:builders: my_package|my_resource_transformer: import: "lib/my_builder.dart" builder_factories: ["myResourceTransformer"] build_extensions: {".svg": ".webp"} auto_apply: dependents build_to: cache - 在项目的
build.release.yaml中配置这个Builder,就像你现在做的一样。
内容的提问来源于stack exchange,提问作者Cododoc
相关产品推荐
相关产品推荐

