(九)Dart Libraries(库)、package(包)

库可以使用 Dart package 工具部署。参考 Pub Package 和 Asset Manager 来获取关于 pub(Dart 的包管理工具) 的更多信息。

使用 importlibrary 指令可以帮助你创建 模块化的可分享的代码。库不仅仅提供 API, 还是一个私有单元:以下划线 (_) 开头的标识符只有在库 内部可见。每个 Dart app 都是一个库, 即使没有使用 library 命令也是一个库。

一、Using libraries(使用库)

使用 import 来指定一个库如何使用另外 一个库。

例如, Dart web 应用通常使用 dart:html 库,然后可以这样导入库:

import 'dart:html';

import 必须参数为库 的 URI。 对于内置的库,URI 使用特殊的 dart: scheme。 对于其他的库,你可以使用文件系统路径或者 package:scheme。package: scheme 指定的库通过包管理器来提供, 例如 pub 工具。

import 'dart:io';
import 'package:mylib/mylib.dart';
import 'package:utils/utils.dart';

注意: URI 代表 uniform resource identifier。 URLs (uniform resource locators) 是一种常见的 URI。

二、Specifying a library prefix(指定库前缀)

如果你导入的两个库具有冲突的标识符, 则你可以使用库的前缀来区分。 例如,如果 library1 和 library2 都有一个名字为 Element 的类, 你可以这样使用:

import 'package:lib1/lib1.dart';
import 'package:lib2/lib2.dart' as lib2;
// ...
Element element1 = new Element();           // 使用lib1的Element .
lib2.Element element2 = new lib2.Element(); // 使用lib2的Element.

三、Importing only part of a library(导入库的一部分)

如果你只使用库的一部分功能,则可以选择需要导入的 内容。例如:

// 仅导入 foo.
import 'package:lib1/lib1.dart' show foo;

// 除了 foo,其他都导入.
import 'package:lib2/lib2.dart' hide foo;

四、Lazily loading a library(延迟载入库)

Deferred loading (也称之为 lazy loading) 可以让应用在需要的时候再 加载库。 下面是一些使用延迟加载库的场景:

  • 减少 APP 的启动时间。
  • 执行 A/B 测试,例如 尝试各种算法的 不同实现。
  • 加载很少使用的功能,例如可选的屏幕和对话框。

要延迟加载一个库,需要先使用 deferred as 来 导入:

import 'package:deferred/hello.dart' deferred as hello;

当需要使用的时候,使用库标识符调用 loadLibrary() 函数来加载库:

greet() async {
  await hello.loadLibrary();
  hello.printGreeting();
}

在前面的代码, 使用 await 关键字暂停代码执行一直到库加载完成。 关于 asyncawait 的更多信息请参考第十章。

在一个库上你可以多次调用 loadLibrary() 函数。 但是该库只是载入一次。

使用延迟加载库的时候,请注意一下问题:
1、延迟加载库的常量在导入的时候是不可用的。 只有当库加载完毕的时候,库中常量才可以使用。
2、在导入文件的时候无法使用延迟库中的类型。 如果你需要使用类型,则考虑把接口类型移动到另外一个库中, 让两个库都分别导入这个接口库。
3、Dart 隐含的把 loadLibrary() 函数导入到使用 deferred as *的命名空间* 中。 loadLibrary() 方法返回一个 Future(详情见第十章)。

五、package(包)Implementing libraries(实现库)

在 Dart 生态中, 库通过包的方式来创建和分发。 Dart 有两种类型的包: 应用包 和 库包

5.1.应用包

5.2.库包

5.2.1.What makes a library package(库包做了啥)

下面显示了最简单的库包的 目录结构:

最简单的库包的 目录结构

对于一个最简单的库需要如下内容:

  • pubspec file
    库的pubspec.yaml 文件和应用包的一样 —并没有特别的标志表明包是 一个库。

  • lib directory
    库包的代码位于 lib 目录中, 在其他包中可以访问这里面的代码。 在 lib 目录下可以创建任意的目录结构。 通常情况下都把实现代码放到 lib/src 目录中。 位于 lib/src 下面的代码被认为是私有的; 其他包不应该直接导入 src/... 里面的代码。 要分享 lib/src 下的 API,你可以在 lib 目录下 创建一个文件,在这个文件中导入 lib/src 中的代码。

注意: 当没有指定 library 指令的时候,根据每个库 的路径和文件名会为每个库生成一个唯一的标签。 所以,我们 建议你不要在代码中使用 library 指令, 除非你想 生成库的 API 文档(详见本文下面的Documenting a library)

在 lib 目录下创建一个主要的库文件( lib/<package-name>.dart),并且在该文件中 导出所有公开的 API。 这样使用你的库的用户就可以只导入一个 文件就可以使用所有的功能了。

lib 目录还可以包含其他重要的非代码文件。例如, 你的库是跨平台的,你创建 了不同平台使用 dart:io 的库。 有些包有几个分开的库需要分别导入, 每个库都使用不同的前缀。

下面是 shelf 库的目录结构。 shelf 库提供了一种简单的方式来创建 web 服务器, shelf 的目录结构是 Dart 库包目录结构 的常见形式:

shelf 的目录结构

在 lib 目录下有个主要的库文件 shelf.dart,该文件导出了 lib/src 目录下的几个文件:

export 'src/cascade.dart';
export 'src/handler.dart';
export 'src/handlers/logger.dart';
export 'src/hijack_exception.dart';
export 'src/middleware.dart';
export 'src/pipeline.dart';
export 'src/request.dart';
export 'src/response.dart';
export 'src/server.dart';
export 'src/server_handler.dart';

shelf 库还包含了一个迷你库: shelf_io。 这个适配器处理 dart:io 中的 HttpRequest 对象。

5.2.2.Organizing a library package

当库包非常小的时候,是非常容易维护、扩展和测试的, 这样的库被称之为 迷你库。 在大部分情况下,每个类都应该位于一个迷你库中, 除非当两个类紧紧耦合在一起的时候需要放到同一个库中。

注意: 你可能已经知道 part 指令了,该指令 可以把一个库分开到多个 Dart 文件中。我们推荐你 使用迷你库,而不要使用该指令。

5.2.3.Importing library files

可以使用 package: 指令并指定文件的 URI 来 导入库文件。

import 'package:utilities/utilities.dart';

当两个文件都位于 lib 目录中 或者目录 lib 之外的时候, 可以使用相对路径来导入库文件。

然后,当导入的文件和使用的文件不在 同一个库的时候,需要使用 package: 指令。 当你不知道如何选择的时候,就使用 package: 指令。

下面显示了在 lib 和 web 库中如何导入 lib/src/foo/a.dart

5.2.4.Providing additional files

良好的库应该很容易测试。 我们推荐你使用 test 库来编写测试代码, 把测试代码放到 test 目录 下。

如果你创建了一个可执行的工具,则可以把 这些工具放到 bin 目录,该目录是公开可访问的。 使用 pub global activate 来启用命令行运行工具的功能。 在 executables 部分 列出所有可执行文件, 可以让用户直接运行该命令,而不用通过 pub global run 来执行。

在库中包含使用你的库的示例代码也是非常有用的,把这些代码 放到 example 目录下。

你在开发的时候创建的其他不应该共享的工具则可以 放到 tool 目录。

当你把库提交到 pub.dartlang.org 的时候,需要包含 README 、 CHANGELOG 等文件, 在 发布包 页面对这些文件有介绍。 同时还请参考 Pub 包约定目录结构 来了解该如何布局包中的文件 目录。

六、Documenting a library(生成库的 API 文档)

使用 dartdoc 工具可以 为库生成 API 文档。 Dartdoc 从代码中解析 使用 /// 语法的 文档注释。

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

参考 shelf 文档 来查看生成的 API 文档格式。

注意: 要包含 库的文档需要使用 library 指令。 参考 issue 1082 了解详情。

七、Distributing a library

当把库项目提交到版本库中的时候,请注意有些 文件是不需要提交的。对于库 不要提交 .packagespubspec.lock 文件, 也不要提交 packages 目录。详情请参考: 哪些文件不需要提交到版本库

使用 pub publish 工具可以在 pub.dartlang.org 上 分享你的库。

发布一个库 描述了一个库需要包含哪些文件。

dartdocs.org 生成器 提供了一些好用的服务供发布到 pub.dartlang.org 的开发者使用。 这些服务追踪库的版本发布,当有新版本发布的时候会自动 生成新的 API 文档,文档在 dartdocs.org 可以查看。 在发布你的库之前,请先运行 dartdoc 看看生成 的文档是否满足你的要求。 如果你的库的文档在 dartdocs.org 中查找不到,请 查看 dartdocs.org/failed 来了解原因。

为了避免版本发布引起的问题, 当引用 dartdocs.org 地址的时候, 可以指定 “latest” 版本来替代具体的版本号。 例如: https://www.dartdocs.org/documentation/shelf/latest/.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容