Freezed包无法为嵌套对象生成toJson代码问题求助
问题背景
在Flutter monorepo架构下,深度嵌套的Freezed模型(User -> UserBankingInfo -> UserDocument)无法生成对应的.g.dart文件,运行build_runner时提示无法为documents(UserDocument类型)生成toJson代码,跨包引用时还会出现.g.dart文件未生成的报错。
三周前更新了Freezed及相关代码生成依赖版本:
- json_annotation: ^4.6.0 => ^4.7.0
- json_serializable: ^6.3.1 => ^6.5.3
- build_runner: ^2.1.10 => ^2.3.2
- freezed: ^2.1.0+1 => ^2.2.0
- freezed_annotation: ^2.0.0 => ^2.2.0
环境信息
- Flutter 3.3.7
- Dart SDK 2.18.4
- monorepo各包均包含Freezed相关依赖,核心代码示例如下:
articles包pubspec.yaml
name: article version: 0.0.1 publish_to: none environment: sdk: ">=2.17.0 <3.0.0" dependencies: common: path: ../common freezed_annotation: ^2.2.0 json_annotation: ^4.7.0 dev_dependencies: build_runner: ^2.1.10 freezed: ^2.1.0+1 json_serializable: ^6.3.1
user.dart
import 'package:common/common.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'user.freezed.dart'; part 'user.g.dart'; @freezed class User with _$User { const User._(); const factory User({ UserBankingInfo? banking_info, }) = _User; factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); }
user_banking_info.dart
import 'package:common/src/entities/user/user_document.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'user_banking_info.freezed.dart'; part 'user_banking_info.g.dart'; @freezed class UserBankingInfo with _$UserBankingInfo { const factory UserBankingInfo({ @Default([]) List<UserDocument> documents, }) = _UserBankingInfo; factory UserBankingInfo.fromJson(Map<String, dynamic> json) => _$UserBankingInfoFromJson(json); }
user_document.dart
import 'package:freezed_annotation/freezed_annotation.dart'; part 'user_document.freezed.dart'; part 'user_document.g.dart'; @freezed class UserDocument with _$UserDocument { const factory UserDocument({ String? id, }) = _UserDocument; factory UserDocument.fromJson(Map<String, dynamic> json) => _$UserDocumentFromJson(json); }
已尝试操作
调整依赖版本(需保留json_annotation: ^4.7.0)、添加analysis_options.yaml和build.yaml配置、测试最新依赖版本、降级Flutter SDK,均未解决问题。
解决方案建议
1. 统一monorepo内所有包的代码生成依赖版本
当前articles包的dev依赖版本与全局更新的版本不一致(如build_runner仍使用旧版^2.1.10),版本冲突是代码生成失败的常见原因。需将所有包的dev依赖版本统一为更新后的版本:
修改articles包的dev_dependencies:
dev_dependencies: build_runner: ^2.3.2 freezed: ^2.2.0 json_serializable: ^6.5.3
同时确保common包的对应依赖版本完全一致,之后在monorepo根目录执行flutter pub get,再逐个包执行依赖安装。
2. 规范跨包模型的导出与引用
确保common包中的模型类通过包入口文件导出,避免直接引用src路径导致代码生成器无法识别:
在common/lib/common.dart中添加导出语句:
export 'src/entities/user/user_document.dart'; export 'src/entities/user/user_banking_info.dart'; export 'src/entities/user/user.dart';
之后在articles包中修改引用路径为import 'package:common/common.dart';,替代直接引用src的写法。
3. 配置build.yaml确保跨包代码生成正常
在monorepo根目录或每个包的目录下创建build.yaml,指定代码生成器的作用范围:
targets: $default: builders: json_serializable: options: generate_for: include: - lib/src/**.dart explicit_to_json: true freezed: options: generate_for: include: - lib/src/**.dart
该配置确保跨包的模型文件被代码生成器正确处理,尤其是explicit_to_json: true会强制生成明确的toJson方法,解决嵌套类型的序列化问题。
4. 清理缓存后重新运行build_runner
执行以下命令彻底清理旧缓存和生成文件,避免干扰:
# 清理全局缓存 flutter pub cache clean # 进入每个包执行清理与构建 cd articles flutter pub run build_runner clean flutter pub run build_runner build --delete-conflicting-outputs cd ../common flutter pub run build_runner clean flutter pub run build_runner build --delete-conflicting-outputs
5. 检查common包的模型生成状态
如果UserDocument的.g.dart文件在common包中也未生成,需优先排查common包的依赖配置,确保其dev_dependencies包含正确版本的build_runner、freezed和json_serializable,并重复上述清理与构建步骤。
内容的提问来源于stack exchange,提问作者peer-f

