内容

创建包

Dart 生态系统使用来共享软件,例如库和工具。本页介绍如何创建标准的共享.

创建新包

#

要创建包的初始目录和结构,请使用dart create命令和package模板

$ dart create -t package <PACKAGE_NAME>

什么是包

#

下图显示了包的最简单布局

root directory contains pubspec.yaml and lib/file.dart

库的最低要求是

pubspec 文件
库的pubspec.yaml文件与应用程序包的相同 - 没有特殊指定来表明包是库。
lib 目录
正如您所料,库代码位于lib目录下,对其他包是公开的。您可以在 lib 下创建任何需要的层次结构。按照惯例,实现代码放在lib/src下。lib/src 下的代码被认为是私有的;其他包永远不需要导入src/...。要使 lib/src 下的 API 公开,您可以从 lib 下的直接文件导出 lib/src 文件。

组织包

#

当您创建小的、独立的库(称为小型库)时,包最容易维护、扩展和测试。在大多数情况下,每个类都应该在它自己的小型库中,除非您遇到两个类紧密耦合的情况。

在 lib 下直接创建一个“主”库文件,lib/<package-name>.dart,它导出所有公共 API。这允许用户通过导入单个文件来获取库的所有功能。

lib 目录还可以包含其他可导入的非 src 库。例如,也许您的主库跨平台工作,但您创建了依赖于dart:iodart:js_interop的单独库。一些包具有单独的库,这些库旨在使用前缀导入,而主库则没有。

让我们看看现实世界包 shelf 的组织结构。shelf包提供了一种使用 Dart 创建 Web 服务器的简便方法,其布局是 Dart 包常用的结构

shelf root directory contains example, lib, test, and tool subdirectories

直接在 lib 下,主库文件shelf.dart导出了lib/src中几个文件的 API。为了避免暴露比预期更多的 API - 以及为开发人员提供整个包的公共 API 概述 - shelf.dart使用show来精确指定要导出的符号

lib/shelf.dart
dart
export 'src/cascade.dart' show Cascade;
export 'src/handler.dart' show Handler;
export 'src/hijack_exception.dart' show HijackException;
export 'src/middleware.dart' show Middleware, createMiddleware;
export 'src/middleware/add_chunked_encoding.dart' show addChunkedEncoding;
export 'src/middleware/logger.dart' show logRequests;
export 'src/middleware_extensions.dart' show MiddlewareExtensions;
export 'src/pipeline.dart' show Pipeline;
export 'src/request.dart' show Request;
export 'src/response.dart' show Response;
export 'src/server.dart' show Server;
export 'src/server_handler.dart' show ServerHandler;

shelf 包还包含一个小型库:shelf_io。此适配器处理来自dart:io的 HttpRequest 对象。

导入库文件

#

从另一个包导入库文件时,请使用package:指令指定该文件的 URI。

dart
import 'package:utilities/utilities.dart';

从您自己的包导入库文件时,请在两个文件都在 lib 内部或两个文件都在 lib 外部时使用相对路径。当导入的文件在 lib 中而导入者在外部时,请使用package:

下图显示了如何从 lib 和 web 中导入lib/foo/a.dart

lib/bar/b.dart uses a relative import; web/main.dart uses a package import

有条件地导入和导出库文件

#

如果您的库支持多个平台,则您可能需要有条件地导入或导出库文件。一个常见的用例是支持 Web 和本机平台的库。

要进行有条件的导入或导出,您需要检查dart:*库的存在。以下是有条件导出代码的示例,该代码检查dart:iodart:js_interop的存在

lib/hw_mp.dart
dart
export 'src/hw_none.dart' // Stub implementation
    if (dart.library.io) 'src/hw_io.dart' // dart:io implementation
    if (dart.library.js_interop) 'src/hw_web.dart'; // package:web implementation

以下代码的作用是

  • 在可以使用dart:io的应用程序(例如,命令行应用程序)中,导出src/hw_io.dart
  • 在可以使用dart:js_interop的应用程序(Web 应用程序)中,导出src/hw_web.dart
  • 否则,导出src/hw_none.dart

要进行有条件的导入文件,请使用与上述相同的代码,但将export更改为import

所有有条件导出的库必须实现相同的 API。例如,以下是dart:io实现

lib/src/hw_io.dart
dart
import 'dart:io';

void alarm([String? text]) {
  stderr.writeln(text ?? message);
}

String get message => 'Hello World from the VM!';

以下是使用抛出UnsupportedError的存根的默认实现

lib/src/hw_none.dart
dart
void alarm([String? text]) => throw UnsupportedError('hw_none alarm');

String get message => throw UnsupportedError('hw_none message');

在任何平台上,您都可以导入具有有条件导出代码的库

dart
import 'package:hw_mp/hw_mp.dart';

void main() {
  print(message);
}

提供其他文件

#

精心设计的包易于测试。我们建议您使用test包编写测试,并将测试代码放在包顶部的test目录中。

如果您创建任何旨在公开使用的命令行工具,请将这些工具放在bin目录中,该目录是公开的。使用dart pub global activate启用从命令行运行工具。在pubspecexecutables部分中列出该工具,允许用户直接运行它,而无需调用dart pub global run.

如果您包含一个如何使用库的示例,将会很有帮助。这将进入包顶部的example目录。

您在开发过程中创建的任何不供公开使用的工具或可执行文件都将进入tool目录。

如果将库发布到pub.dev站点,则需要其他文件,例如README.mdCHANGELOG.md,在发布包中描述。有关如何组织包目录的更多信息,请参见pub 包布局约定.

记录库

#

您可以使用dart doc工具为库生成 API 文档。dart doc解析源代码以查找文档注释,这些注释使用///语法

dart
/// The event handler responsible for updating the badge in the UI.
void updateBadge() {
  ...
}

有关生成文档的示例,请参见shelf 文档.

要在生成的文档中包含任何库级文档,请添加library指令并将注释直接附加在其上方。有关记录库的方式和原因,请参见有效 Dart:文档.

分发开源库

#

如果您的库是开源的,我们建议您在pub.dev 网站上共享它。要发布或更新库,请使用pub publish,该命令会上传您的包并创建或更新其页面。例如,请参见shelf 包的页面。有关如何准备包以供发布的详细信息,请参见发布包.

pub.dev 网站不仅托管您的包,还生成并托管您的包的 API 参考文档。包的关于框中有一个指向最新生成文档的链接;例如,请参见 shelf 包的API 文档。指向先前版本文档的链接位于包页面的版本选项卡中。

要确保您的包的 API 文档在 pub.dev 网站上看起来不错,请执行以下步骤

  • 在发布包之前,请运行dart doc工具以确保您的文档成功生成并按预期显示。
  • 发布包后,请检查**版本**选项卡以确保文档已成功生成。
  • 如果文档根本没有生成,请在**版本**选项卡中点击**失败**以查看`dart doc`输出。

资源

#

使用以下资源来了解更多关于包的信息