Flutter代码预构建生成插件prebuild_code_generator的使用

Flutter代码预构建生成插件prebuild_code_generator的使用

本包使用build_runner来预先构建protobuf、图像和字符串资源的代码。

特性

  • <code>proto_builder</code>:为protobuf生成dart代码、java代码和Object-C代码。
  • <code>image_res_builder</code>:为图像资源生成ImageProvider对象。
  • <code>string_res_builder</code>:从json文件加载并读取字符串资源的代码。

开始使用

在你的Flutter项目的pubspec.yaml中添加以下依赖:

dev_dependencies:
  ...
  build_runner: ^2.1.0
  prebuild_code_generator: <latest_version>

为你的Flutter项目添加一个build.yaml文件,用于配置生成器。如果在此处未配置生成器,则会禁用该生成器。以下是一个build.yaml的示例:

targets:
  $default:
    sources:
      - $package$
      - lib/$lib$
      # 资源路径的正则表达式
      - assets/**
      # proto路径的正则表达式
      - proto/**
    builders:
      prebuild_code_generator:string_res_builder:
        options:
          # 多语言字符串资源路径
          input_path:
            en: "assets/strings/strings_en.json"
            zh: "assets/strings/strings_zh.json"
          # 生成代码的目录
          output_dir: "lib/res_gen"
          # 默认语言用于生成字符串资源的键
          # 如果未配置,默认值为"en"
          default_lang: en
          # 如果设置为true,则只生成字符串资源的键,不会生成加载代码
          only_gen_key: false
      prebuild_code_generator:proto_builder:
        options:
          # proto目录
          proto_dir: "proto/"
          # protoc版本,参见 https://github.com/protocolbuffers/protobuf/releases
          protoc_version: "3.19.4"
          dart:
            # 启用生成dart代码
            enable: true
            # protoc_gen_dart版本,参见 https://pub.dev/packages/protoc_plugin
            protoc_gen_dart_version: "20.0.0"
            # 生成dart代码的目录
            output_dir: "lib/proto_gen/"
          java:
            # 启用生成java代码
            enable: true
            # protoc-gen-grpc-java版本,参见 https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/
            protoc-gen-grpc-java: "1.44.0"
            # 生成java代码的目录
            output_dir: "android/app/src/main/proto_gen/"
          oc:
            # 启用生成object-c代码
            enable: true
            # 生成object-c代码的目录
            output_dir: "ios/Classes/Protos/"
      prebuild_code_generator:image_res_builder:
        options:
          # 图像资源目录
          # 你还需要在pubspec.yaml中进行配置,例如:
          # 在assets部分添加:
          #  assets:
          #    - assets/images/
          image_dir:
            - "assets/images/"
            - "assets/animations/"
          # 生成代码的目录
          output_dir: "lib/res_gen"

将proto和资源文件放入build.yaml中配置的相应目录中。然后运行以下命令来生成代码:

dart run build_runner build

在Flutter项目代码中使用生成的代码。详情请参见示例:

import 'package:example/res_gen/image_res.g.dart';
import 'package:example/res_gen/string_res.g.dart';
import 'package:example/res_gen/string_res_key.g.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 加载字符串资源
  await StringRes.getInstance().load();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  State<StatefulWidget> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              StringRes.getString(StringResKey.ok),
            ),
            Text(
              StringRes.getString(StringResKey.hello, params: ["jack"]),
            ),
            Image(
              image: Assets.images.checkbtnChecked,
              width: 40,
              height: 40,
            ),
            Image(
              image: Assets.images.close,
              width: 40,
              height: 40,
            ),
            Image(
              image: Assets.animations.refreshLoading,
              width: 40,
              height: 40,
            )
          ],
        ),
      ),
    );
  }
}

示例代码

以下是完整的示例代码:

import 'package:example/res_gen/image_res.g.dart';
import 'package:example/res_gen/string_res.g.dart';
import 'package:example/res_gen/string_res_key.g.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await StringRes.getInstance().load();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  [@override](/user/override)
  State<StatefulWidget> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              StringRes.getString(StringResKey.ok),
            ),
            Text(
              StringRes.getString(StringResKey.hello, params: ["jack"]),
            ),
            Image(
              image: Assets.images.checkbtnChecked,
              width: 40,
              height: 40,
            ),
            Image(
              image: Assets.images.close,
              width: 40,
              height: 40,
            ),
            Image(
              image: Assets.animations.refreshLoading,
              width: 40,
              height: 40,
            )
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用prebuild_code_generator插件的示例代码案例。这个插件通常用于在构建应用之前自动生成一些代码文件,以提高开发效率和代码维护性。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加prebuild_code_generator的依赖:

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  build_runner: ^2.1.4  # build_runner是运行代码生成工具的必要依赖
  prebuild_code_generator: ^x.y.z  # 替换为实际的版本号

2. 创建代码生成配置

接下来,你需要创建一个配置文件来指定代码生成的行为。通常,这个配置文件会放在build.yaml中:

targets:
  $default:
    builders:
      prebuild_code_generator:prebuild:
        enabled: true

3. 定义代码生成逻辑

现在,你需要创建一个Dart文件来定义代码生成的逻辑。例如,可以创建一个code_generator.dart文件:

import 'package:build/build.dart';

Builder prebuild(BuilderOptions options) {
  return (BuildStep buildStep) async {
    // 读取输入文件(如果有)
    var inputId = buildStep.inputId;
    var content = await buildStep.readAsString(inputId);

    // 这里可以添加你的代码生成逻辑
    // 例如,基于输入内容生成新的代码文件
    var generatedCode = '''
// This is auto-generated code
class AutoGeneratedClass {
  void sayHello() {
    print('Hello, World!');
  }
}
''';

    // 输出生成的代码到指定的位置
    var outputId = inputId.changeExtension('.g.dart');
    await buildStep.writeAsString(outputId, generatedCode);
  };
}

4. 运行代码生成器

在命令行中,运行以下命令来执行代码生成器:

flutter pub run build_runner build

这个命令会根据build.yaml中的配置和code_generator.dart中定义的逻辑生成代码文件。

5. 使用生成的代码

在Flutter项目的其他部分中,你可以像使用普通Dart文件一样使用生成的代码。例如,如果生成的代码文件名为auto_generated_class.g.dart,你可以这样使用它:

import 'auto_generated_class.g.dart';

void main() {
  var autoGenerated = AutoGeneratedClass();
  autoGenerated.sayHello();  // 输出: Hello, World!
}

注意事项

  • 确保build_runnerprebuild_code_generator的版本兼容。
  • 在实际项目中,代码生成逻辑可能会更加复杂,可能需要根据项目的特定需求进行定制。
  • 生成的代码文件通常会被放置在.dart_tool/build/generated目录下,这是build_runner的默认行为。

这个示例展示了如何使用prebuild_code_generator插件在Flutter项目中自动生成代码。根据具体需求,你可以进一步扩展和优化代码生成逻辑。

回到顶部