.flu-cli.json 配置详解
核心地位
.flu-cli.json 是 Flu CLI 生态系统的核心配置文件,它驱动着 CLI 和 VSCode 扩展的所有核心功能:
| 功能 | 关联配置 | 说明 |
|---|---|---|
| 智能文件生成 | generators.<type>.path | 右键生成时自动定位到配置的目录 |
| 智能代码片段 | withBasePage | 为 true 时显示 BasePage 相关代码片段 |
| Smart Init | withBasePage | 自动检测 BasePage 是否存在,不存在则降级为原生模式 |
| ViewModel 联动 | withViewModel | 生成 Page 时自动创建对应的 ViewModel |
| 基类继承 | withBase* / base*Class / base*Import | 控制生成代码是否继承自定义基类 |
💡 提示:无论你在项目的哪个目录右键生成文件,扩展都会根据此配置自动将文件创建到正确的位置。
配置文件位置
配置文件应放在 Flutter 项目根目录(与 pubspec.yaml 同级):
my_app/
├── lib/
├── pubspec.yaml
└── .flu-cli.json # ← 核心配置文件初始化配置文件
方式 1:右键菜单(推荐)
- 在项目根目录右键
- 选择
Flu: 初始化项目 - 自动生成
.flu-cli.json
方式 2:命令面板
- 打开命令面板(
Cmd+Shift+P/Ctrl+Shift+P) - 输入
Flu: Init - 自动生成配置文件
方式 3:CLI 命令
cd your-flutter-project
flu-cli config init方式 4:手动创建
在项目根目录创建 .flu-cli.json 文件,复制以下最小配置:
{
"generators": {
"page": {
"path": "lib/pages",
"defaultType": "stateful",
"withViewModel": false,
"withBasePage": false
},
"viewModel": {
"path": "lib/viewmodels"
},
"widget": {
"path": "lib/widgets"
},
"model": {
"path": "lib/models"
}
}
}配置项速查表
通用配置项(所有生成器可用)
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
path | string | 因生成器而异 | 文件生成路径,支持 {feature} 占位符 |
fileSuffix | string | 因生成器而异 | 文件名后缀,如 _page、_viewmodel |
fileName | string | - | 自定义完整文件名(覆盖默认命名规则) |
defaultType | "stateful" | "stateless" | "stateful" | 默认 Widget 类型(仅 page/widget 可用) |
Page 生成器专用
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
withViewModel | boolean | true | 是否同时生成 ViewModel 文件 |
viewModelPath | string | 同 viewModel.path | Page 生成时 ViewModel 的目标路径 |
withBasePage | boolean | false | 是否继承 BasePage |
basePageClass | string | "BasePage" | BasePage 类名 |
basePageImport | string | - | BasePage 导入路径 |
ViewModel 生成器专用
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
withBaseViewModel | boolean | false | 是否继承 BaseViewModel |
baseViewModelClass | string | "BaseViewModel" | BaseViewModel 类名 |
baseViewModelImport | string | - | BaseViewModel 导入路径 |
Widget 生成器专用
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
withBaseWidget | boolean | false | 是否继承 BaseWidget |
baseWidgetClass | string | "BaseWidget" | BaseWidget 类名 |
baseWidgetImport | string | - | BaseWidget 导入路径 |
Model 生成器专用
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
withBaseModel | boolean | false | 是否继承 BaseModel |
baseModelClass | string | "BaseModel" | BaseModel 类名 |
baseModelImport | string | - | BaseModel 导入路径 |
配置结构
完整结构预览
{
"generators": {
"page": { ... },
"viewModel": { ... },
"widget": { ... },
"component": { ... },
"model": { ... },
"service": { ... },
"module": { ... }
}
}generators
generators 对象包含所有生成器的配置,每个生成器对应一种文件类型。
Page 生成器配置
Page 生成器是最常用的生成器,支持最多的配置项。
完整配置参考
{
"generators": {
"page": {
"path": "lib/pages",
"fileSuffix": "_page",
"fileName": "",
"defaultType": "stateful",
"withViewModel": true,
"viewModelPath": "lib/viewmodels",
"withBasePage": true,
"basePageClass": "BasePage",
"basePageImport": "package:my_app/core/base/base_page.dart"
}
}
}配置项详解
| 配置项 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
path | string | "lib/pages" | 否 | 页面文件生成路径,支持 {feature} 占位符 |
fileSuffix | string | "_page" | 否 | 文件名后缀,如 home → home_page.dart |
fileName | string | - | 否 | 自定义完整文件名(覆盖默认命名) |
defaultType | string | "stateful" | 否 | 默认页面类型:"stateful" 或 "stateless" |
withViewModel | boolean | true | 否 | 是否同时生成对应的 ViewModel 文件 |
viewModelPath | string | 同 viewModel.path | 否 | 指定 ViewModel 生成路径(优先级高于 viewModel.path) |
withBasePage | boolean | false | 否 | 是否继承自定义 BasePage |
basePageClass | string | "BasePage" | 当 withBasePage: true | BasePage 类名 |
basePageImport | string | - | 当 withBasePage: true | BasePage 的导入路径 |
配置与功能联动
withBasePage 对代码片段的影响
withBasePage 值 | 代码片段行为 |
|---|---|
true | 显示 stPage (BasePage) 和 viewmodel 代码片段 |
false | 隐藏 stPage 和 viewmodel,仅显示 stSimplePage |
Smart Init 行为
当你使用 Flu: Init 或 flu-cli config init 时,工具会自动检测项目中是否存在 BasePage 文件:
- 存在:设置
withBasePage: true - 不存在:自动降级为
withBasePage: false(原生模式)
检测路径:
lib/base/base_page.dartlib/core/base/base_page.dartlib/core/presentation/base/base_page.dartbasePageImport指定的路径
使用示例
示例 1:基础配置(原生模式)
{
"generators": {
"page": {
"path": "lib/pages",
"defaultType": "stateful",
"withViewModel": false,
"withBasePage": false
}
}
}生成 home 页面:
lib/pages/
└── home_page.dart # 标准 StatefulWidget示例 2:带 ViewModel 联动
{
"generators": {
"page": {
"path": "lib/pages",
"withViewModel": true
},
"viewModel": {
"path": "lib/viewmodels"
}
}
}生成 home 页面:
lib/pages/
└── home_page.dart
lib/viewmodels/
└── home_viewmodel.dart # 自动联动生成示例 3:使用 BasePage 架构
{
"generators": {
"page": {
"path": "lib/pages",
"withBasePage": true,
"basePageClass": "BasePage",
"basePageImport": "package:my_app/core/base/base_page.dart",
"withViewModel": true
}
}
}生成的代码:
import 'package:flutter/material.dart';
import 'package:my_app/core/base/base_page.dart';
import '../viewmodels/home_viewmodel.dart';
class HomePage extends BasePage<HomeViewModel> {
const HomePage({Key? key}) : super(key: key);
@override
HomeViewModel createViewModel() => HomeViewModel();
@override
Widget buildPage(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Container(),
);
}
}示例 4:模块化路径(使用 {feature} 占位符)
{
"generators": {
"page": {
"path": "lib/features/{feature}/pages",
"viewModelPath": "lib/features/{feature}/viewmodels",
"withViewModel": true
}
}
}在 lib/features/user/pages 生成页面时,{feature} 会自动替换为 user。
ViewModel 生成器配置
完整配置参考
{
"generators": {
"viewModel": {
"path": "lib/viewmodels",
"fileSuffix": "_viewmodel",
"fileName": "",
"withBaseViewModel": true,
"baseViewModelClass": "BaseViewModel",
"baseViewModelImport": "package:my_app/core/base/base_viewmodel.dart"
}
}
}配置项详解
| 配置项 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
path | string | "lib/viewmodels" | 否 | ViewModel 生成路径,支持 {feature} 占位符 |
fileSuffix | string | "_viewmodel" | 否 | 文件名后缀,如 home → home_viewmodel.dart |
fileName | string | - | 否 | 自定义完整文件名 |
withBaseViewModel | boolean | false | 否 | 是否继承 BaseViewModel |
baseViewModelClass | string | "BaseViewModel" | 当 withBaseViewModel: true | BaseViewModel 类名 |
baseViewModelImport | string | - | 当 withBaseViewModel: true | BaseViewModel 导入路径 |
配置与功能联动
withBaseViewModel 值 | 行为 |
|---|---|
true | 生成的 ViewModel 继承 BaseViewModel,包含 init()、setLoading() 等方法 |
false | 生成纯净的 ChangeNotifier 类 |
使用示例
示例 1:基础 ViewModel
{
"generators": {
"viewModel": {
"path": "lib/viewmodels",
"withBaseViewModel": false
}
}
}生成的代码:
import 'package:flutter/foundation.dart';
class HomeViewModel extends ChangeNotifier {
bool _isLoading = false;
bool get isLoading => _isLoading;
Future<void> loadData() async {
_isLoading = true;
notifyListeners();
try {
// TODO: 加载数据
} finally {
_isLoading = false;
notifyListeners();
}
}
}示例 2:使用 BaseViewModel
{
"generators": {
"viewModel": {
"path": "lib/viewmodels",
"withBaseViewModel": true,
"baseViewModelClass": "BaseViewModel",
"baseViewModelImport": "package:my_app/core/base/base_viewmodel.dart"
}
}
}生成的代码:
import 'package:my_app/core/base/base_viewmodel.dart';
class HomeViewModel extends BaseViewModel {
@override
Future<void> init() async {
// TODO: 初始化逻辑
}
Future<void> loadData() async {
setLoading(true);
try {
// TODO: 加载数据
} catch (e) {
handleError(e);
} finally {
setLoading(false);
}
}
}Widget 生成器配置
完整配置参考
{
"generators": {
"widget": {
"path": "lib/widgets",
"fileSuffix": "",
"fileName": "",
"defaultType": "stateless",
"withBaseWidget": false,
"baseWidgetClass": "BaseWidget",
"baseWidgetImport": "package:my_app/core/base/base_widget.dart"
}
}
}配置项详解
| 配置项 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
path | string | "lib/widgets" | 否 | Widget 生成路径,支持 {feature} 占位符 |
fileSuffix | string | "" | 否 | 文件名后缀(通常为空) |
fileName | string | - | 否 | 自定义完整文件名 |
defaultType | string | "stateless" | 否 | 默认 Widget 类型:"stateful" 或 "stateless" |
withBaseWidget | boolean | false | 否 | 是否继承 BaseWidget |
baseWidgetClass | string | "BaseWidget" | 当 withBaseWidget: true | BaseWidget 类名 |
baseWidgetImport | string | - | 当 withBaseWidget: true | BaseWidget 导入路径 |
使用示例
{
"generators": {
"widget": {
"path": "lib/shared/widgets",
"defaultType": "stateless"
}
}
}生成 user_card 组件:
lib/shared/widgets/
└── user_card.dartComponent 生成器配置
Component 生成器与 Widget 生成器配置相同,用于生成业务组件。
完整配置参考
{
"generators": {
"component": {
"path": "lib/components",
"fileSuffix": "",
"defaultType": "stateless"
}
}
}配置项与 Widget 生成器相同,请参考上方 Widget 生成器配置。
Model 生成器配置
完整配置参考
{
"generators": {
"model": {
"path": "lib/models",
"fileSuffix": "_model",
"fileName": "",
"withBaseModel": false,
"baseModelClass": "BaseModel",
"baseModelImport": "package:my_app/core/base/base_model.dart"
}
}
}配置项详解
| 配置项 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
path | string | "lib/models" | 否 | Model 生成路径,支持 {feature} 占位符 |
fileSuffix | string | "_model" | 否 | 文件名后缀,如 user → user_model.dart |
fileName | string | - | 否 | 自定义完整文件名 |
withBaseModel | boolean | false | 否 | 是否继承 BaseModel |
baseModelClass | string | "BaseModel" | 当 withBaseModel: true | BaseModel 类名 |
baseModelImport | string | - | 当 withBaseModel: true | BaseModel 导入路径 |
使用示例
{
"generators": {
"model": {
"path": "lib/models",
"fileSuffix": "_model"
}
}
}生成 user 模型:
class UserModel {
final String id;
final String name;
UserModel({
required this.id,
required this.name,
});
factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
id: json['id'] as String,
name: json['name'] as String,
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
};
}
UserModel copyWith({
String? id,
String? name,
}) {
return UserModel(
id: id ?? this.id,
name: name ?? this.name,
);
}
}Service 生成器配置
完整配置参考
{
"generators": {
"service": {
"path": "lib/services",
"fileSuffix": "_service"
}
}
}配置项详解
| 配置项 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
path | string | "lib/services" | 否 | Service 生成路径 |
fileSuffix | string | "_service" | 否 | 文件名后缀 |
Module 生成器配置
Module 生成器用于一次性创建完整的功能模块目录结构。
完整配置参考
{
"generators": {
"module": {
"path": "lib/features/{feature}"
}
}
}配置项详解
| 配置项 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
path | string | "lib/features/{feature}" | 否 | Module 生成路径,{feature} 会替换为模块名 |
使用示例
生成 user 模块:
lib/features/user/
├── pages/
├── viewmodels/
├── widgets/
├── services/
├── models/
└── index.dart占位符
配置中支持以下占位符:
{feature}
表示功能模块名称,会根据生成位置自动推断。
配置示例:
{
"generators": {
"page": {
"path": "lib/features/{feature}/pages"
},
"viewModel": {
"path": "lib/features/{feature}/viewmodels"
}
}
}行为:
在 lib/features/user/pages 生成页面时:
{feature}=user- Page 路径:
lib/features/user/pages/xxx_page.dart - ViewModel 路径:
lib/features/user/viewmodels/xxx_viewmodel.dart
完整配置示例
示例 1:Lite 项目(简单结构)
适用于小型项目、快速原型。
{
"generators": {
"page": {
"path": "lib/pages",
"defaultType": "stateful",
"withViewModel": true,
"withBasePage": true,
"basePageClass": "BasePage",
"basePageImport": "lib/base/base_page.dart"
},
"viewModel": {
"path": "lib/viewmodels",
"withBaseViewModel": true,
"baseViewModelClass": "BaseViewModel",
"baseViewModelImport": "lib/base/base_viewmodel.dart"
},
"widget": {
"path": "lib/widgets",
"defaultType": "stateless"
},
"model": {
"path": "lib/models"
},
"service": {
"path": "lib/services"
}
}
}示例 2:Modular 项目(模块化结构)
适用于中大型项目,推荐使用。
{
"generators": {
"page": {
"path": "lib/features/{feature}/pages",
"defaultType": "stateful",
"withViewModel": true,
"viewModelPath": "lib/features/{feature}/viewmodels",
"withBasePage": true,
"basePageClass": "BasePage",
"basePageImport": "lib/core/base/base_page.dart"
},
"viewModel": {
"path": "lib/features/{feature}/viewmodels",
"withBaseViewModel": true,
"baseViewModelClass": "BaseViewModel",
"baseViewModelImport": "lib/core/base/base_viewmodel.dart"
},
"widget": {
"path": "lib/shared/widgets",
"defaultType": "stateless"
},
"model": {
"path": "lib/shared/models"
},
"component": {
"path": "lib/features/{feature}/components"
},
"module": {
"path": "lib/features/{feature}"
}
}
}示例 3:Clean Architecture 项目
适用于企业级应用。
{
"generators": {
"page": {
"path": "lib/features/{feature}/presentation/pages",
"defaultType": "stateful",
"withViewModel": true,
"viewModelPath": "lib/features/{feature}/presentation/viewmodels",
"withBasePage": false
},
"viewModel": {
"path": "lib/features/{feature}/presentation/viewmodels",
"withBaseViewModel": false
},
"widget": {
"path": "lib/features/{feature}/presentation/widgets",
"defaultType": "stateless"
},
"model": {
"path": "lib/features/{feature}/data/models"
},
"service": {
"path": "lib/features/{feature}/data/datasources"
},
"component": {
"path": "lib/features/{feature}/presentation/components"
},
"module": {
"path": "lib/features/{feature}"
}
}
}示例 4:原生模式(不使用基类)
适用于已有项目或不需要 MVVM 架构的场景。
{
"generators": {
"page": {
"path": "lib/pages",
"defaultType": "stateful",
"withViewModel": false,
"withBasePage": false
},
"viewModel": {
"path": "lib/viewmodels",
"withBaseViewModel": false
},
"widget": {
"path": "lib/widgets",
"defaultType": "stateless"
},
"model": {
"path": "lib/models"
}
}
}配置优先级
如果项目中没有 .flu-cli.json,扩展会使用默认配置:
- 用户配置(
.flu-cli.json)- 最高优先级 - 默认配置(扩展内置)- 备选
配置验证
扩展会自动验证配置文件:
有效配置示例
{
"generators": {
"page": {
"path": "lib/pages"
}
}
}无效配置示例
{
"generators": {
"page": {
"path": 123 // ❌ 错误:path 必须是字符串
}
}
}如果配置无效,扩展会:
- 显示错误提示
- 使用默认配置
- 在输出面板显示详细错误信息
常见问题
配置不生效?
- 确认配置文件在项目根目录(与
pubspec.yaml同级) - 检查 JSON 格式是否正确(可使用 JSONLint 验证)
- 重新加载 VSCode 窗口(
Cmd+Shift+P→Developer: Reload Window)
如何重置配置?
删除 .flu-cli.json 文件,重新运行 Flu: Init 初始化。
多个项目如何共享配置?
- 创建配置模板文件
- 复制到每个项目
- 根据项目需要调整
配置文件应该提交到 Git 吗?
推荐提交,这样团队成员可以使用统一的配置。
在 .gitignore 中 不要 忽略 .flu-cli.json。
withBasePage 设置了 true 但代码片段不显示?
确认项目中存在 BasePage 文件,检查以下路径:
lib/base/base_page.dartlib/core/base/base_page.dartbasePageImport指定的路径
如果文件不存在,Smart Init 会自动降级为原生模式。