gpt4 book ai didi

Dart build runner 生成一个包含内容的 dart 文件

转载 作者:行者123 更新时间:2023-12-03 02:44:39 25 4
gpt4 key购买 nike

我正在开发一个包含 200 多个模型的 dart 包,目前我必须为每个模型手动编写一行“导出”,以使使用此包的每个人都可以使用这些模型。

我希望构建运行程序生成一个包含每个导出定义的 dart 文件。

因此,我会创建一个注释“ExportModel”。构建器应搜索使用此注释注释的每个类。

我尝试创建一些构建器,但它们会为每个被注释的类生成一个 *.g.dart 文件。我只想拥有一个文件。

在哪里可以创建只运行一次并在最后创建文件的构建器?

最佳答案

对仅运行一次并在包中创建单个文件的构建器问题的简短回答是使用 r'$lib$'作为输入扩展。长答案是,要找到被注释的类,您可能需要一个中间输出来跟踪它们。
我会用 2 个构建器来写这个,一个是为了搜索 ExportModel注释,另一个写入导出文件。这是一个省略了细节的粗略草图 - 我没有测试过这里的任何代码,但它应该让你开始走上正确的道路。
Builder 1 - 找到用 @ExportModel() 注释的类.
可以使用来自 package:source_gen 的一些实用程序进行编写,但不能使用 LibraryBuilder因为它没有输出 Dart 代码......
目标是写一个.exports每个文件旁边的文件 .dart文件作为所有用 @ExportModel() 注释的类的名称.

class ExportLocatingBuilder implements Builder {
@override
final buildExtensions = const {
'.dart': ['.exports']
};

@override
Future<void> build(BuildStep buildStep) async {
final resolver = buildStep.resolver;
if (!await resolver.isLibrary(buildStep.inputId)) return;
final lib = LibraryReader(await buildStep.inputLibrary);
final exportAnnotation = TypeChecker.fromRuntime(ExportModel);
final annotated = [
for (var member in lib.annotatedWith(exportAnnotation)) element.name,
];
if (annotated.isNotEmpty) {
buildStep.writeAsString(
buildStep.inputId.changeExtension('.exports'), annotated.join(','));
}
}
}
这个构建器应该是 build_to: cache你可能想要一个 PostProcessBuilder清除它产生的所有输出,这些输出将用 applies_builder 指定.您可以使用 FileDeletingBuilder 以低成本实现清理。见 the FAQ关于临时输出和 angular cleanup例如。
Builder 2 - 找到 .exports文件并生成一个 Dart 文件
使用 findAssets 追踪所有这些 .exports文件,并写一个 export每个人的声明。使用 show文件的内容应该包含被注释的成员的名称。
class ExportsBuilder implements Builder {
@override
final buildExtensions = const {
r'$lib$': ['exports.dart']
};

@override
Future<void> build(BuildStep buildStep) async {
final exports = buildStep.findAssets(Glob('**/*.exports'));
final content = [
await for (var exportLibrary in exports)
'export \'${exportLibrary.changeExtension('.dart').uri}\' '
'show ${await buildStep.readAsString(exportLibrary)};',
];
if (content.isNotEmpty) {
buildStep.writeAsString(
AssetId(buildStep.inputId.package, 'lib/exports.dart'),
content.join('\n'));
}
}
}
这个构建器应该是 build_to: source如果您想在 pub 上发布此文件。它应该有一个 required_inputs: [".exports"]以确保它在前一个构建器之后运行。
为什么需要这么复杂?
您可以将其实现为使用 findAssets 的单个构建器。找到所有的 Dart 文件。缺点是重建会慢得多,因为它会因任何 Dart 文件中的任何内容更改而失效,并且您最终会解析所有 Dart 代码以查找任何 Dart 代码中的更改。使用 2 builder 方法,则只有个人 .exports来自更改的 Dart 文件的文件需要解析并在更改时重建,然后只有当导出更改时 exports.dart文件无效。 build_runner 的旧版本也不支持使用 Resolver解决不是从输入库中传递导入的代码。 build_runner最新版本放宽了这个限制。

关于Dart build runner 生成一个包含内容的 dart 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56972823/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com