Flutter自动生成代码插件ds_flutter_gen_runner的使用

Flutter自动生成代码插件ds_flutter_gen_runner的使用

Logo

Pub Build Status Coverage

该插件用于为您的资源(如资产、字体、颜色等)生成Dart代码,从而消除所有基于字符串的API。

注意:这是flutter_gen的一个分支。优先使用原版。

灵感来源于SwiftGen

动机

直接使用资源路径字符串并不安全。

# pubspec.yaml
flutter:
  assets:
    - assets/images/profile.jpg

如果拼写错误会发生什么?

Widget build(BuildContext context) {
  return Image.asset('assets/images/profile.jpeg');
}

// 抛出异常:
// 无法加载资源:assets/images/profile.jpeg

⭕️ 我们希望安全地使用它们。

Widget build(BuildContext context) {
  return Assets.images.profile.image();
}

安装过程

Homebrew

适用于macOS和Linux。

brew install FlutterGen/tap/fluttergen

asdf

适用于macOS和Linux。 asdf-fluttergen与mise兼容。

# 添加插件
asdf plugin add fluttergen
# 或
asdf plugin add fluttergen https://github.com/FlutterGen/asdf-fluttergen.git

# 安装fluttergen
asdf install fluttergen latest

参见:FlutterGen/asdf-fluttergen

Pub Global

适用于macOS、Linux和Windows。

dart pub global activate ds_flutter_gen

可能需要设置路径

作为build_runner的一部分

  1. 在项目的pubspec.yaml文件中添加build_runnerds_flutter_gen_runner依赖:
dev_dependencies:
  build_runner:
  ds_flutter_gen_runner:
  1. 安装flutter_gen
flutter pub get
  1. 使用flutter_gen
dart run build_runner build

GitHub Actions

适用于macOS和Linux。

- uses: FlutterGen/setup-fluttergen@v1
  with:
    version: ${{ fluttergen_version }}

参见:FlutterGen/setup-fluttergen

使用方法

在配置了pubspec.yaml之后运行fluttergen命令。

fluttergen -h

fluttergen -c example/pubspec.yaml

配置文件

ds_flutter_gen根据pubspec.yaml中的flutterds_flutter_gen键生成Dart文件。

默认配置可以在这里找到:这里

# pubspec.yaml
# ...

ds_flutter_gen:
  output: lib/gen/ # 可选,默认为lib/gen/
  line_length: 80 # 可选,默认为80

  # 可选
  integrations:
    flutter_svg: true
    flare_flutter: true
    rive: true
    lottie: true

flutter:
  uses-material-design: true
  assets:
    - assets/images/

  fonts:
    - family: Raleway
      fonts:
        - asset: assets/fonts/Raleway-Regular.ttf
        - asset: assets/fonts/Raleway-Italic.ttf
          style: italic

build.yaml

你也可以在build.yaml中配置生成选项,它会在读取pubspec.yaml之前被读取。

# build.yaml
# ...

targets:
  $default:
    builders:
      ds_flutter_gen_runner: # 或者 flutter_gen
        options: 
          output: lib/build_gen/ # 可选,默认为lib/gen/
          line_length: 120 # 可选,默认为80

可用解析器

资源

遵循文档 添加资源和图片#指定资源 来指定资源,然后ds_flutter_gen将生成相关的Dart文件。 无需其他特定配置。

# pubspec.yaml
flutter:
  assets:
    - assets/images/
    - assets/images/chip3/chip.jpg
    - assets/images/chip4/chip.jpg
    - assets/images/icons/paint.svg
    - assets/images/icons/dart@test.svg
    - assets/json/fruits.json
    - assets/flare/Penguin.flr
    - assets/rive/vehicles.riv
    - pictures/ocean_view.jpg

这些配置将在默认情况下在lib/gen/目录下生成assets.gen.dart文件。

带口味的资源

Flutter支持 基于口味有条件地捆绑资源。 仅在指定了口味时,资源才可用。 ds_flutter_gen将生成指定的flavors,无论当前的口味是什么。 可以通过.flavors访问flavors字段,例如:

print(MyAssets.images.chip4.flavors); // -> {'extern'}
排除生成特定资源

你可以使用Glob模式指定ds_flutter_gen > assets > exclude以排除特定资源。

ds_flutter_gen:
  assets:
    exclude:
      - folder-your-want-to-exclude/**
      - specified-asset.jpg

更多模式可以查看package:glob

为包生成资源

如果你想要为一个包生成资源, 可以在ds_flutter_gen > assets > outputs下使用package_parameter_enabled

ds_flutter_gen:
  assets:
    outputs:
      package_parameter_enabled: true # <- 添加此行。

这会向生成的类添加包常量。例如:

class Assets {
  Assets._();

  static const String package = 'test';

  static const $AssetsImagesGen images = $AssetsImagesGen();
  static const $AssetsUnknownGen unknown = $AssetsUnknownGen();
}

然后你可以隐式或显式地使用包中的资源:

// 隐式使用 `Image`/`SvgPicture`/`Lottie`。
Widget build(BuildContext context) {
  return Assets.images.icons.paint.svg(
    width: 120,
    height: 120,
  );
}

或者

// 显式使用 `Image`/`SvgPicture`/`Lottie`。
Widget build(BuildContext context) {
  return SvgPicture.asset(
    Assets.images.icons.paint.path,
    package: Assets.package,
    width: 120,
    height: 120,
  );
}
生成目录路径

如果你想生成目录路径, 可以在ds_flutter_gen > assets > outputs下使用directory_path_enabled

ds_flutter_gen:
  assets:
    outputs:
      directory_path_enabled: true # <- 添加此行。

这会向生成的目录类添加path获取器。例如:

class $AssetsImagesGen {
  const $AssetsImagesGen();

  ///******

  /// 目录路径:assets/images
  String get path => 'assets/images';
}
包含额外元数据

在构建时,可以通过使用parse_metadata选项包含生成类中的额外元数据。

ds_flutter_gen:
  parse_metadata: true # <- 添加此行(默认为false)

对于基于图像的资源,将在生成的类中添加新的可空size字段。例如:

AssetGenImage get logo =>
  const AssetGenImage('assets/images/logo.png', size: Size(209.0, 49.0));

现在可以在运行时不从实际资源中解析信息。

Widget build(BuildContext context) {
  return Assets.images.logo.size!.width;
}
使用示例

ds_flutter_gen会为Flutter支持的图像格式生成Image类。

assets/images/chip.jpg的结果示例:

  • <strong>Assets.images.chip</strong><a href="https://api.flutter.dev/flutter/painting/AssetImage-class.html"><code>AssetImage 类</code></a> 的实现。
  • <strong>Assets.images.chip.image(...)</strong> 返回 <a href="https://api.flutter.dev/flutter/widgets/Image-class.html"><code>Image 类</code></a>
  • <strong>Assets.images.chip.provider(...)</strong> 返回 <a href="https://api.flutter.dev/flutter/painting/ImageProvider-class.html"><code>ImageProvider 类</code></a>
  • <strong>Assets.images.chip.path</strong> 只返回路径字符串。
  • <strong>Assets.images.chip.values</strong> 只返回值列表。
Widget build(BuildContext context) {
  return Assets.images.chip.image();
}

Widget build(BuildContext context) {
  return Assets.images.chip.image(
    width: 120,
    height: 120,
    fit: BoxFit.scaleDown,
  );

Widget build(BuildContext context) {
  // Assets.images.chip.path = 'assets/images/chip3/chip3.jpg'
  return Image.asset(Assets.images.chip.path);
}

如果你使用了 <a href="https://pub.dev/packages/flutter_svg">flutter_svg</a> 的SVG图像,你可以使用集成功能。

# pubspec.yaml
ds_flutter_gen:
  integrations:
    flutter_svg: true

flutter:
  assets:
    - assets/images/icons/paint.svg
Widget build(BuildContext context) {
  return Assets.images.icons.paint.svg(
    width: 120,
    height: 120
  );
}

可用集成

插件 文件扩展名 设置 使用
flutter_svg .svg flutter_svg: true Assets.images.icons.paint.svg()
flare_flutter .flr flare_flutter: true Assets.flare.penguin.flare()
rive .flr rive: true Assets.rive.vehicles.rive()
lottie .json, .zip lottie: true Assets.lottie.hamburgerArrow.lottie()

在其他情况下,资源将以String类的形式生成。

// 如果不使用集成。
final svg = SvgPicture.asset(Assets.images.icons.paint);

final json = await rootBundle.loadString(Assets.json.fruits);

ds_flutter_gen还支持生成其他样式的Assets类:

# pubspec.yaml
ds_flutter_gen:
  assets:
    outputs: 
      # Assets.imagesChip
      # style: camel-case

      # Assets.images_chip
      # style: snake-case

      # Assets.images.chip (默认样式)
      # style: dot-delimiter

flutter:
  assets:
    - assets/images/chip.png

根目录将被省略,如果它是assetsasset

assets/images/chip3/chip.jpg      => Assets.images.chip3.chip
assets/images/chip4/chip.jpg      => Assets.images.chip4.chip
assets/images/icons/paint.svg     => Assets.images.icons.paint
assets/images/icons/dart@test.svg => Assets.images.icons.dartTest
assets/json/fruits.json           => Assets.json.fruits
pictures/ocean_view.jpg           => Assets.pictures.oceanView

示例代码由FlutterGen生成

字体

只需遵循文档 使用自定义字体 来指定字体,然后ds_flutter_gen将生成相关的Dart文件。 无需其他特定配置。

# pubspec.yaml
flutter:
  fonts:
    - family: Raleway
      fonts:
        - asset: assets/fonts/Raleway-Regular.ttf
        - asset: assets/fonts/Raleway-Italic.ttf
          style: italic
    - family: RobotoMono
      fonts:
        - asset: assets/fonts/RobotoMono-Regular.ttf
        - asset: assets/fonts/RobotoMono-Bold.ttf
          weight: 700

这些配置将在默认情况下在lib/gen/目录下生成fonts.gen.dart文件。

为包生成字体

如果你想要为一个包生成字体, 可以在ds_flutter_gen > fonts > outputs下使用package_parameter_enabled

ds_flutter_gen:
  fonts:
    outputs:
      package_parameter_enabled: true # <- 添加此行。

这会向生成的类添加包常量。例如:

class Fonts {
  Fonts._();

  static const String package = 'test';

  static const String raleway = 'packages/$package/Raleway';
  static const String robotoMono = 'packages/$package/RobotoMono';
}
使用示例
Text(
  'Hi there, I\'m FlutterGen',
  style: TextStyle(
    fontFamily: FontFamily.robotoMono,
    fontFamilyFallback: const [FontFamily.raleway],
  ),
)

示例代码由FlutterGen生成

颜色

ds_flutter_gen 支持从 XML 格式的文件生成颜色。

# pubspec.yaml
ds_flutter_gen:
  colors:
    inputs:
      - assets/color/colors.xml
      - assets/color/colors2.xml

ds_flutter_gen 可以基于name属性和颜色十六进制值生成一个 <a href="https://api.flutter.dev/flutter/material/Colors-class.html">Color</a> 类。 如果元素具有type属性,则将生成一种特殊颜色。

目前支持的特殊颜色类型:

  • <a href="https://api.flutter.dev/flutter/material/MaterialColor-class.html">MaterialColor</a>
  • <a href="https://api.flutter.dev/flutter/material/MaterialAccentColor-class.html">MaterialAccentColor</a>
<color name="milk_tea">#F5CB84</color>
<color name="cinnamon" type="material">#955E1C</color>
<color name="yellow_ocher" type="material material-accent">#DF9527</color>

这些配置将在默认情况下在lib/gen/目录下生成colors.gen.dart文件。

使用示例
Text(
  'Hi there, I\'m FlutterGen',
  style: TextStyle(
    color: ColorName.denim,
  ),

更多关于Flutter自动生成代码插件ds_flutter_gen_runner的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自动生成代码插件ds_flutter_gen_runner的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


ds_flutter_gen_runner 是一个用于 Flutter 项目的代码生成工具,它可以帮助开发者自动生成一些重复性的代码,例如路由生成、状态管理、模型类等,从而提高开发效率。以下是如何使用 ds_flutter_gen_runner 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 ds_flutter_gen_runner 的依赖。通常,它需要 build_runner 来执行代码生成任务。

dev_dependencies:
  ds_flutter_gen_runner: ^版本号
  build_runner: ^2.1.0

请确保将 ^版本号 替换为你实际需要的 ds_flutter_gen_runner 版本。

2. 创建配置文件

ds_flutter_gen_runner 通常需要一个配置文件来指定生成代码的规则。这个配置文件可以是一个 YAML 文件或 Dart 文件,具体取决于插件的实现。

例如,如果你需要生成路由代码,可能会有一个 ds_flutter_gen.yaml 文件:

routes:
  - name: HomePage
    path: '/home'
  - name: SettingsPage
    path: '/settings'

3. 运行代码生成器

在配置好依赖和配置文件后,你可以使用 build_runner 来生成代码。在终端中运行以下命令:

flutter pub run build_runner build

这条命令会执行代码生成任务,并根据配置文件生成相应的 Dart 代码。

4. 使用生成的代码

生成的代码通常会放在 lib/generated/ 目录下(具体路径可能因插件而异)。你可以在你的项目中使用这些生成的代码,例如:

import 'generated/routes.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: generatedRoutes,
      initialRoute: '/home',
    );
  }
}

5. 持续集成与开发

在开发过程中,你可能需要多次运行代码生成器。可以使用 watch 模式来自动检测文件变化并重新生成代码:

flutter pub run build_runner watch

这将使 build_runner 监视文件变化,并在需要时自动重新生成代码。

6. 清理生成的代码

如果你想清理生成的代码,可以运行以下命令:

flutter pub run build_runner clean

这将删除所有由 build_runner 生成的文件。

7. 示例

假设你正在使用 ds_flutter_gen_runner 生成路由代码,配置文件 ds_flutter_gen.yaml 如下:

routes:
  - name: HomePage
    path: '/home'
  - name: SettingsPage
    path: '/settings'

运行 flutter pub run build_runner build 后,生成的路由代码可能如下:

// lib/generated/routes.dart
import 'package:flutter/material.dart';
import 'package:my_app/pages/home_page.dart';
import 'package:my_app/pages/settings_page.dart';

final Map<String, WidgetBuilder> generatedRoutes = {
  '/home': (context) => HomePage(),
  '/settings': (context) => SettingsPage(),
};

然后在 main.dart 中使用这些生成的路由:

import 'package:flutter/material.dart';
import 'generated/routes.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: generatedRoutes,
      initialRoute: '/home',
    );
  }
}
回到顶部