Skip to content

.flu-cli.json 配置详解

核心地位

.flu-cli.jsonFlu CLI 生态系统的核心配置文件,它驱动着 CLI 和 VSCode 扩展的所有核心功能:

功能关联配置说明
智能文件生成generators.<type>.path右键生成时自动定位到配置的目录
智能代码片段withBasePagetrue 时显示 BasePage 相关代码片段
Smart InitwithBasePage自动检测 BasePage 是否存在,不存在则降级为原生模式
ViewModel 联动withViewModel生成 Page 时自动创建对应的 ViewModel
基类继承withBase* / base*Class / base*Import控制生成代码是否继承自定义基类

💡 提示:无论你在项目的哪个目录右键生成文件,扩展都会根据此配置自动将文件创建到正确的位置。

配置文件位置

配置文件应放在 Flutter 项目根目录(与 pubspec.yaml 同级):

my_app/
├── lib/
├── pubspec.yaml
└── .flu-cli.json    # ← 核心配置文件

初始化配置文件

方式 1:右键菜单(推荐)

  1. 在项目根目录右键
  2. 选择 Flu: 初始化项目
  3. 自动生成 .flu-cli.json

方式 2:命令面板

  1. 打开命令面板(Cmd+Shift+P / Ctrl+Shift+P
  2. 输入 Flu: Init
  3. 自动生成配置文件

方式 3:CLI 命令

bash
cd your-flutter-project
flu-cli config init

方式 4:手动创建

在项目根目录创建 .flu-cli.json 文件,复制以下最小配置:

json
{
    "generators": {
        "page": {
            "path": "lib/pages",
            "defaultType": "stateful",
            "withViewModel": false,
            "withBasePage": false
        },
        "viewModel": {
            "path": "lib/viewmodels"
        },
        "widget": {
            "path": "lib/widgets"
        },
        "model": {
            "path": "lib/models"
        }
    }
}

配置项速查表

通用配置项(所有生成器可用)

配置项类型默认值说明
pathstring因生成器而异文件生成路径,支持 {feature} 占位符
fileSuffixstring因生成器而异文件名后缀,如 _page_viewmodel
fileNamestring-自定义完整文件名(覆盖默认命名规则)
defaultType"stateful" | "stateless""stateful"默认 Widget 类型(仅 page/widget 可用)

Page 生成器专用

配置项类型默认值说明
withViewModelbooleantrue是否同时生成 ViewModel 文件
viewModelPathstringviewModel.pathPage 生成时 ViewModel 的目标路径
withBasePagebooleanfalse是否继承 BasePage
basePageClassstring"BasePage"BasePage 类名
basePageImportstring-BasePage 导入路径

ViewModel 生成器专用

配置项类型默认值说明
withBaseViewModelbooleanfalse是否继承 BaseViewModel
baseViewModelClassstring"BaseViewModel"BaseViewModel 类名
baseViewModelImportstring-BaseViewModel 导入路径

Widget 生成器专用

配置项类型默认值说明
withBaseWidgetbooleanfalse是否继承 BaseWidget
baseWidgetClassstring"BaseWidget"BaseWidget 类名
baseWidgetImportstring-BaseWidget 导入路径

Model 生成器专用

配置项类型默认值说明
withBaseModelbooleanfalse是否继承 BaseModel
baseModelClassstring"BaseModel"BaseModel 类名
baseModelImportstring-BaseModel 导入路径

配置结构

完整结构预览

json
{
  "generators": {
    "page": { ... },
    "viewModel": { ... },
    "widget": { ... },
    "component": { ... },
    "model": { ... },
    "service": { ... },
    "module": { ... }
  }
}

generators

generators 对象包含所有生成器的配置,每个生成器对应一种文件类型。

Page 生成器配置

Page 生成器是最常用的生成器,支持最多的配置项。

完整配置参考

json
{
    "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"
        }
    }
}

配置项详解

配置项类型默认值必填说明
pathstring"lib/pages"页面文件生成路径,支持 {feature} 占位符
fileSuffixstring"_page"文件名后缀,如 homehome_page.dart
fileNamestring-自定义完整文件名(覆盖默认命名)
defaultTypestring"stateful"默认页面类型:"stateful""stateless"
withViewModelbooleantrue是否同时生成对应的 ViewModel 文件
viewModelPathstringviewModel.path指定 ViewModel 生成路径(优先级高于 viewModel.path
withBasePagebooleanfalse是否继承自定义 BasePage
basePageClassstring"BasePage"withBasePage: trueBasePage 类名
basePageImportstring-withBasePage: trueBasePage 的导入路径

配置与功能联动

withBasePage 对代码片段的影响

withBasePage代码片段行为
true显示 stPage (BasePage) 和 viewmodel 代码片段
false隐藏 stPageviewmodel,仅显示 stSimplePage

Smart Init 行为

当你使用 Flu: Initflu-cli config init 时,工具会自动检测项目中是否存在 BasePage 文件:

  • 存在:设置 withBasePage: true
  • 不存在:自动降级为 withBasePage: false(原生模式)

检测路径:

  • lib/base/base_page.dart
  • lib/core/base/base_page.dart
  • lib/core/presentation/base/base_page.dart
  • basePageImport 指定的路径

使用示例

示例 1:基础配置(原生模式)

json
{
    "generators": {
        "page": {
            "path": "lib/pages",
            "defaultType": "stateful",
            "withViewModel": false,
            "withBasePage": false
        }
    }
}

生成 home 页面:

lib/pages/
└── home_page.dart    # 标准 StatefulWidget

示例 2:带 ViewModel 联动

json
{
    "generators": {
        "page": {
            "path": "lib/pages",
            "withViewModel": true
        },
        "viewModel": {
            "path": "lib/viewmodels"
        }
    }
}

生成 home 页面:

lib/pages/
└── home_page.dart

lib/viewmodels/
└── home_viewmodel.dart    # 自动联动生成

示例 3:使用 BasePage 架构

json
{
    "generators": {
        "page": {
            "path": "lib/pages",
            "withBasePage": true,
            "basePageClass": "BasePage",
            "basePageImport": "package:my_app/core/base/base_page.dart",
            "withViewModel": true
        }
    }
}

生成的代码:

dart
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} 占位符)

json
{
    "generators": {
        "page": {
            "path": "lib/features/{feature}/pages",
            "viewModelPath": "lib/features/{feature}/viewmodels",
            "withViewModel": true
        }
    }
}

lib/features/user/pages 生成页面时,{feature} 会自动替换为 user

ViewModel 生成器配置

完整配置参考

json
{
    "generators": {
        "viewModel": {
            "path": "lib/viewmodels",
            "fileSuffix": "_viewmodel",
            "fileName": "",
            "withBaseViewModel": true,
            "baseViewModelClass": "BaseViewModel",
            "baseViewModelImport": "package:my_app/core/base/base_viewmodel.dart"
        }
    }
}

配置项详解

配置项类型默认值必填说明
pathstring"lib/viewmodels"ViewModel 生成路径,支持 {feature} 占位符
fileSuffixstring"_viewmodel"文件名后缀,如 homehome_viewmodel.dart
fileNamestring-自定义完整文件名
withBaseViewModelbooleanfalse是否继承 BaseViewModel
baseViewModelClassstring"BaseViewModel"withBaseViewModel: trueBaseViewModel 类名
baseViewModelImportstring-withBaseViewModel: trueBaseViewModel 导入路径

配置与功能联动

withBaseViewModel行为
true生成的 ViewModel 继承 BaseViewModel,包含 init()setLoading() 等方法
false生成纯净的 ChangeNotifier

使用示例

示例 1:基础 ViewModel

json
{
    "generators": {
        "viewModel": {
            "path": "lib/viewmodels",
            "withBaseViewModel": false
        }
    }
}

生成的代码:

dart
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

json
{
    "generators": {
        "viewModel": {
            "path": "lib/viewmodels",
            "withBaseViewModel": true,
            "baseViewModelClass": "BaseViewModel",
            "baseViewModelImport": "package:my_app/core/base/base_viewmodel.dart"
        }
    }
}

生成的代码:

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 生成器配置

完整配置参考

json
{
    "generators": {
        "widget": {
            "path": "lib/widgets",
            "fileSuffix": "",
            "fileName": "",
            "defaultType": "stateless",
            "withBaseWidget": false,
            "baseWidgetClass": "BaseWidget",
            "baseWidgetImport": "package:my_app/core/base/base_widget.dart"
        }
    }
}

配置项详解

配置项类型默认值必填说明
pathstring"lib/widgets"Widget 生成路径,支持 {feature} 占位符
fileSuffixstring""文件名后缀(通常为空)
fileNamestring-自定义完整文件名
defaultTypestring"stateless"默认 Widget 类型:"stateful""stateless"
withBaseWidgetbooleanfalse是否继承 BaseWidget
baseWidgetClassstring"BaseWidget"withBaseWidget: trueBaseWidget 类名
baseWidgetImportstring-withBaseWidget: trueBaseWidget 导入路径

使用示例

json
{
    "generators": {
        "widget": {
            "path": "lib/shared/widgets",
            "defaultType": "stateless"
        }
    }
}

生成 user_card 组件:

lib/shared/widgets/
└── user_card.dart

Component 生成器配置

Component 生成器与 Widget 生成器配置相同,用于生成业务组件。

完整配置参考

json
{
    "generators": {
        "component": {
            "path": "lib/components",
            "fileSuffix": "",
            "defaultType": "stateless"
        }
    }
}

配置项与 Widget 生成器相同,请参考上方 Widget 生成器配置。


Model 生成器配置

完整配置参考

json
{
    "generators": {
        "model": {
            "path": "lib/models",
            "fileSuffix": "_model",
            "fileName": "",
            "withBaseModel": false,
            "baseModelClass": "BaseModel",
            "baseModelImport": "package:my_app/core/base/base_model.dart"
        }
    }
}

配置项详解

配置项类型默认值必填说明
pathstring"lib/models"Model 生成路径,支持 {feature} 占位符
fileSuffixstring"_model"文件名后缀,如 useruser_model.dart
fileNamestring-自定义完整文件名
withBaseModelbooleanfalse是否继承 BaseModel
baseModelClassstring"BaseModel"withBaseModel: trueBaseModel 类名
baseModelImportstring-withBaseModel: trueBaseModel 导入路径

使用示例

json
{
    "generators": {
        "model": {
            "path": "lib/models",
            "fileSuffix": "_model"
        }
    }
}

生成 user 模型:

dart
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 生成器配置

完整配置参考

json
{
    "generators": {
        "service": {
            "path": "lib/services",
            "fileSuffix": "_service"
        }
    }
}

配置项详解

配置项类型默认值必填说明
pathstring"lib/services"Service 生成路径
fileSuffixstring"_service"文件名后缀

Module 生成器配置

Module 生成器用于一次性创建完整的功能模块目录结构。

完整配置参考

json
{
    "generators": {
        "module": {
            "path": "lib/features/{feature}"
        }
    }
}

配置项详解

配置项类型默认值必填说明
pathstring"lib/features/{feature}"Module 生成路径,{feature} 会替换为模块名

使用示例

生成 user 模块:

lib/features/user/
├── pages/
├── viewmodels/
├── widgets/
├── services/
├── models/
└── index.dart

占位符

配置中支持以下占位符:

{feature}

表示功能模块名称,会根据生成位置自动推断。

配置示例

json
{
    "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 项目(简单结构)

适用于小型项目、快速原型。

json
{
    "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 项目(模块化结构)

适用于中大型项目,推荐使用。

json
{
    "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 项目

适用于企业级应用。

json
{
    "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 架构的场景。

json
{
    "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,扩展会使用默认配置:

  1. 用户配置.flu-cli.json)- 最高优先级
  2. 默认配置(扩展内置)- 备选

配置验证

扩展会自动验证配置文件:

有效配置示例

json
{
    "generators": {
        "page": {
            "path": "lib/pages"
        }
    }
}

无效配置示例

json
{
    "generators": {
        "page": {
            "path": 123  // ❌ 错误:path 必须是字符串
        }
    }
}

如果配置无效,扩展会:

  1. 显示错误提示
  2. 使用默认配置
  3. 在输出面板显示详细错误信息

常见问题

配置不生效?

  1. 确认配置文件在项目根目录(与 pubspec.yaml 同级)
  2. 检查 JSON 格式是否正确(可使用 JSONLint 验证)
  3. 重新加载 VSCode 窗口(Cmd+Shift+PDeveloper: Reload Window

如何重置配置?

删除 .flu-cli.json 文件,重新运行 Flu: Init 初始化。

多个项目如何共享配置?

  1. 创建配置模板文件
  2. 复制到每个项目
  3. 根据项目需要调整

配置文件应该提交到 Git 吗?

推荐提交,这样团队成员可以使用统一的配置。

.gitignore不要 忽略 .flu-cli.json

withBasePage 设置了 true 但代码片段不显示?

确认项目中存在 BasePage 文件,检查以下路径:

  • lib/base/base_page.dart
  • lib/core/base/base_page.dart
  • basePageImport 指定的路径

如果文件不存在,Smart Init 会自动降级为原生模式。


下一步

相关链接

Released under the MIT License.