介绍一下包
使用package可以创建共享的模块化代码。一个最小的package包括:
- 一个pubspeck.yaml文件:声明了package的名称、版本、和作者等的元数据文件。
- 一个lib文件夹:包括公开的pubulic代码,最少应该有一个
<package-name>.dart
文件。
Flutter Packages分为两类:
- Dart包:其中一些可能包含Flutter的特定功能,因此对Flutter框架具有依赖性,这种包仅用于Flutter。
- 插件包:一种专用的Dart包,其中包含Dart编写的API,以及针对安卓和iOS平台的特定实现,就是说插件包括原生代码。
开发Dart Packages
第一步创建Dart包
你可以使用如下命令创建DartPackages
1 | flutter create -template=package charles_package |
这将在charles_package/文件夹下创建一个具有以下专用内容的package工程:
- lib/mypackage.dart: Package的Dart代码
- test/charles_package_test.dart: Package的单元测试代码。
实现Package
对于纯Dart包,只需要在lib/
下面我们看看如何组织package包的代码,以shelf package为例,它的目录结构如下:
在lib根目录下的shelf.dart中导出了多个lib/src目录下的dart文件:
1 | export 'src/cascade.dart'; |
而package中主要的功能源码都在src下。shelf package也导出了一个mini库:shelf_io,它主要是处理HttpRequest的。
导入包,当需要使用这个package时,我们可以通过package:指令来指定包的入口文件:
1 | import 'pakcage:utilities/utilities.dart'; |
同一个包中的源码文件之间也可以使用相对路径来导入。
生成文档
可以使用dartdoc工具来为package生成文档,开发者需要做的就是遵守文档注释语法在代码中添加文档注释,最后使用dartdoc可以直接生成API文档(一个静态网站)。文档注释是使用三斜线’///‘开始,如:
1 | /// The event handler responseible for updating the badge in the UI. |
处理包的相互依赖
如果我们正在开发一个charles_package包,它依赖于另一个包,则需要将该依赖包添加到pubspec.yaml文件的dependencies部分。这与在Flutter 应用程序或任何其他Dart项目中引用软件包没有什么不同。但是,如果charles_package包碰巧是一个插件包,其平台特定的代码需要访问url_launcher公开的特定于平台的API,那么我们还需要为特定于平台的构建文件添加合适的依赖声明,如下所示:
Android
在charles_package/android/build.gradle
:
1 | android{ |
您现在就可以在charles_package/android/src
源码中import io.flutter.plugins.urllauncher.UrlLauncherPlugin
访问UrlLauncherPlugin类
。
iOS
在charles_package/ios/charles_package.podspec
:
1 | Pod::Spec.new do |s| |
你现在就可以在charles_package/ios/classes源码中 #import "UrlLauncherPlugin.h"
然后访问UrlLauncherPlugin类。
解决依赖冲突
假设我们想在charles_package
包中使用some_package
和 other_package
,并且这两个包都依赖url_launcher
,但是依赖的是url_launcher
的不同版本。那我们就有潜在冲突。避免这种情况的最好方法是在指定依赖关系时,使用版本范围而不是特定版本。
1 | dependencies: |
如果some_package
声明了上面的依赖关系,other_package
声明了url_launcher
版本像’0.4.5’或’^0.4.0’时,pub将能够自动解决问题。
即使some_package
和other_package
声明了不兼容的url_lancher
版本,它仍然可能会和url_launcher
以兼容的方式正常工作。你可以通过向charles_package
包的pubspeck.yaml
文件中添加依赖性覆盖声明来处理冲突,从而强制使用特定版本:
强制使用0.4.3
版本的url_lancher
,在charles_package/pubspec.yaml
中:
1 | dependencies: |
如果冲突依赖不是一个包,而是一个特定于Android
的库,比如guava
,那么必须将依赖重写声明添加到Gradle构建逻辑中。
强制使用23.0版本的guava库,在charles_package/android/build.gradle
中:
1 | configurations.all{ |
Cocoapods
目前不提供依赖覆盖功能。
发布Package
一旦实现了一个包,我们可以在Pub上发布它,这样其他开发者可以轻松使用它。
在发布前,检查pubspec.yaml
、README.md
以及CHANGELOG.md
文件,以确保其内容的完整性和正确性。然后运行dry-run命令以查看是否都准备好了。
1 | flutter packages pub publish --dry-run |
验证无误后,我们就可以运行发布命令了:
1 | flutter pakcages pub publish |