美文网首页Dart语法糖
(九)Dart Libraries(库)、package(包)

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

作者: 小哥_xiaoge | 来源:发表于2019-06-03 00:06 被阅读100次

    库可以使用 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/.

    相关文章

      网友评论

        本文标题:(九)Dart Libraries(库)、package(包)

        本文链接:https://www.haomeiwen.com/subject/qfasaqtx.html