dart-cli-app-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Dart CLI Application Best Practices

Dart CLI应用最佳实践

1. When to use this skill

1. 何时使用此技能

Use this skill when:
  • Creating a new Dart CLI application.
  • Refactoring an existing CLI entrypoint (
    bin/
    ).
  • Reviewing CLI code for quality and standards.
  • Setting up executable scripts for Linux/Mac.
使用场景:
  • 创建新的Dart CLI应用。
  • 重构现有CLI入口点(
    bin/
    目录)。
  • 审查CLI代码的质量与标准合规性。
  • 为Linux/Mac系统设置可执行脚本。

2. Best Practices

2. 最佳实践

Entrypoint Structure (
bin/
)

入口点结构(
bin/

Keep the contents of your entrypoint file (e.g.,
bin/my_app.dart
) minimal. This improves testability by decoupling logic from the process runner.
DO:
dart
// bin/my_app.dart
import 'package:my_app/src/entry_point.dart';

Future<void> main(List<String> arguments) async {
  await runApp(arguments);
}
DON'T:
  • Put complex logic directly in
    bin/my_app.dart
    .
  • Define classes or heavy functions in the entrypoint.
保持入口点文件(如
bin/my_app.dart
)的内容尽可能精简。通过将逻辑与进程运行器解耦,提升可测试性。
推荐做法:
dart
// bin/my_app.dart
import 'package:my_app/src/entry_point.dart';

Future<void> main(List<String> arguments) async {
  await runApp(arguments);
}
不推荐做法:
  • bin/my_app.dart
    中直接编写复杂逻辑。
  • 在入口点中定义类或复杂函数。

Executable Scripts

可执行脚本

For CLI tools intended to be run directly on Linux and Mac, add a shebang and ensure the file is executable.
DO:
  1. Add
    #!/usr/bin/env dart
    to the first line.
  2. Run
    chmod +x bin/my_script.dart
    to make it executable.
dart
#!/usr/bin/env dart

void main() => print('Ready to run!');
针对要在Linux和Mac上直接运行的CLI工具,添加shebang并确保文件具备可执行权限。
推荐做法:
  1. 在文件首行添加
    #!/usr/bin/env dart
  2. 运行
    chmod +x bin/my_script.dart
    赋予可执行权限。
dart
#!/usr/bin/env dart

void main() => print('Ready to run!');

Process Termination (
exitCode
)

进程终止(
exitCode

Properly handle process termination to allow for debugging and correct status reporting.
DO:
  • Use the
    exitCode
    setter to report failure.
  • Allow
    main
    to complete naturally.
  • Use standard exit codes (sysexits) for clarity (e.g.,
    64
    for bad usage,
    78
    for configuration errors).
    • See
      package:io
      ExitCode
      class or FreeBSD sysexits man page.
dart
import 'dart:io';

void main() {
  if (someFailure) {
    exitCode = 64; // DO!
    return;
  }
}
AVOID:
  • Calling
    exit(code)
    directly, as it terminates the VM immediately, preventing "pause on exit" debugging and
    finally
    blocks from running.
正确处理进程终止,以便于调试和状态报告。
推荐做法:
  • 使用
    exitCode
    设置器报告失败状态。
  • main
    函数自然执行完成。
  • 使用标准退出码(sysexits)以确保清晰性(例如,
    64
    表示使用错误,
    78
    表示配置错误)。
    • 可参考
      package:io
      ExitCode
      类或FreeBSD的sysexits手册页。
dart
import 'dart:io';

void main() {
  if (someFailure) {
    exitCode = 64; // 推荐做法!
    return;
  }
}
避免:
  • 直接调用
    exit(code)
    ,因为它会立即终止VM,导致“退出时暂停”调试功能失效,且
    finally
    代码块无法执行。

Exception Handling

异常处理

Uncaught exceptions automatically set a non-zero exit code, but you should handle expected errors gracefully.
Example:
dart
Future<void> main(List<String> arguments) async {
  try {
    await runApp(arguments);
  } catch (e, stack) {
    print('App crashed!');
    print(e);
    print(stack);
    exitCode = 1; // Explicitly fail
  }
}
未捕获的异常会自动设置非零退出码,但你仍需优雅处理预期错误。
示例:
dart
Future<void> main(List<String> arguments) async {
  try {
    await runApp(arguments);
  } catch (e, stack) {
    print('App crashed!');
    print(e);
    print(stack);
    exitCode = 1; // 显式标记失败
  }
}

3. Recommended Packages

3. 推荐包

Use these community-standard packages to solve common CLI problems:
CategoryRecommended PackageUsage
Stack Traces
package:stack_trace
detailed, cleaner stack traces
Version Info
package:build_version
automatic version injection
Arg Parsing
package:args
standard flag/option parsing
CLI Generation
package:build_cli
generate arg parsers from classes
Configuration
package:checked_yaml
precise YAML parsing with line numbers
Configuration
package:json_serializable
strongly typed config objects
Testing
package:test_process
integration testing for CLI apps
Testing
package:test_descriptor
file system fixtures for tests
Networking
package:http
standard HTTP client (remember user-agent!)
使用这些社区标准包解决常见CLI问题:
分类推荐包用途
堆栈跟踪
package:stack_trace
详细、更清晰的堆栈跟踪
版本信息
package:build_version
自动注入版本信息
参数解析
package:args
标准的标记/选项解析
CLI生成
package:build_cli
从类生成参数解析器
配置处理
package:checked_yaml
带行号的精确YAML解析
配置处理
package:json_serializable
强类型配置对象
测试
package:test_process
CLI应用的集成测试
测试
package:test_descriptor
测试用的文件系统夹具
网络请求
package:http
标准HTTP客户端(记得设置User-Agent!)

4. Conventions

4. 约定

  • File Caching: Write cached files to
    .dart_tool/[pkg_name]/
    .
  • User-Agent: Always set a User-Agent header in HTTP requests, including version info.
  • ANSI Output: Use
    package:io
    for handling ANSI colors and styles.
  • 文件缓存:将缓存文件写入
    .dart_tool/[pkg_name]/
    目录。
  • User-Agent:在HTTP请求中始终设置User-Agent头,包含版本信息。
  • ANSI输出:使用
    package:io
    处理ANSI颜色与样式。