初步了解flutter pubspec.yaml

包管理工具Pub


Dart提供了包管理工具Pub,用于管理代码,资源,版本。Dart 生态系统使用包来管理共享软件,比如:库和工具。我们使用Pub包管理工具 来获取Dart包。在Pub上,可以找到公开可用的包。或者从本地文件系统或其他的位置,比如Git仓库,加载可用的包。无论包是从什么途径加载的, Pub 都会进行版本依赖管理,从而帮助我们获得版本兼容的软件包以及SDK。类似于Android 中的 JCenter/Maven、iOS 中的 CocoaPods、前端中的 npm 库。

Pub工具包含管理 Package 、部署 Package 和部署命令行应用的命令。

在Dart中库和应用都属于包。pubspec.yaml是包的配置文件,包含了元数据(包的名称,版本),运行环境(DartSDK,FlutterSDK版本),外部依赖,内部配置(资源管理等)。每一个Dart包目录中至少包含一个pubspec文件。

下面我们一起来看下 pubspec.yaml文件详细介绍:
 

# 项目名称,必填字端
name: newtify


# 版本号,非必填
# 若需要将项目托管在pub.dev则该字段必填。
version: 1.2.3


# 项目描述,非必填
# 若需要将项目托管在pub.dev则该字段必填。
description: >-
  Have you been turned into a newt?  Would you like to be?
  This package can help. It has all of the
  newt-transmogrification functionality you have been looking
  for.


# 项目主页,非必填
# 该项目的介绍主页,填写域名
homepage: https://example-pet-store.com/newtify


# 开发文档位置,非必填
# 与`homepage`不同,若该项目还包含其他文档,可以将文档的地址添加到该节点下。如果项目托管在pub.dev,该节点显示项目的API信息。
documentation: https://example-pet-store.com/newtify/docs


# 项目的远程库,非必填
# 若该项目是lib或开源库,这个配置文件用于关联库的来源地址,最好填写有效的地址,否则会无法关联获取项目。
repository: https://github.com//


# 问题追踪页面,非必填
# 若该项目是一个开源且随时更新的项目,可以通过填写该属性,标明该项目的问题追踪文档站点,如果使用pub.dev来进行项目托管,则pub.dev将尝试通过该字段显示该项目的问题跟踪链接。若该项目托管在github,则可以将该字段填写为github的issues
issue_tracker: https://github.com///issues


# 项目的第三方插件依赖,在这个标签中列出了该项目正常工作所需的每一个软件包与版本。以下通过实例详解该标签的详情
dependencies:
  # 实例1 直接写明约束版本,若该插件是发布在https://pub.dev/ 之上,IDE会直接在项目目录下执行`flutter packages get`来下载其插件的最新版本
  transmogrify: 
  # 实例2 该插件是在实例1的基础上进行延伸,其中`^1.4.0`的含义是约束了版本号,也就是在该项目中,需要使用1.4.0版本
  transmogrify: ^1.4.0
  #实例3 若该插件未部署在pub.dev之上,则可以通过URL来指定出插件下载的源
  transmogrify:
    hosted:
      name: transmogrify
      url: http://some-package-server.com
  #实例4 基于实例3,其中version表明了使用该插件的版本信息
  transmogrify:
    hosted:
      name: transmogrify
      url: http://some-package-server.com
    version: ^1.4.0
  #实例5 若该插件是发布在git上,可以用以下方式来进行插件获取,默认获取master下代码
  transmogrify:
    git:
      url: git://github.com/munificent/kittens.git
  #实例6 基于实例5,其中ref标明获取的分支信息
  transmogrify:
    git:
      url: git://github.com/munificent/kittens.git
      ref: some-branch
  #实例7 基于实例5,若插件只是在项目中的某一个目录中,可以通过path来指定插件位置
  transmogrify:
    git:
      url: git://github.com/munificent/kittens.git
      path: path/to/kittens
  #实例8 若插件在本地某一目录,可以通过指定path来找到该插件
  transmogrify:
    path: /Users/me/transmogrify


  #指定版本,若该项目使用的插件需要约束版本,则方法如下
  #实例1 在该项目中,此插件指定版本为1.4.0
  transmogrify: ^1.4.0
  #实例2 在该项目中,此插件最低版本为1.2.3
  transmogrify: ">=1.2.3"
  #实例3 在该项目中,此插件最低支持2.0.0版本,但不支持3.0.0以上版本
  transmogrify: ">=2.0.0 <3.0.0"
  #实例4 在该项目中,此插件最高支持到1.2.3以下版本
  transmogrify: "<1.2.3"


  #指定Flutter SDK
  #实例1 项目必填项,指定SDK,并获取SDK最新版
  flutter:
    sdk: flutter
  #实例2 基于实例1,指定SDK版本号
  flutter:
    sdk: flutter
    version: ">=2.0.0-dev.68.0 <3.0.0"
  #实例3 另外一种写法
  flutter_driver:
    sdk: flutter
    version: ^0.0.1


# 区别于dependencies标签,dependencies是生产环境依赖库版本,dev_dependencies是开发环境依赖库版本,该环境仅在开发调试时使用。标签规则同dependencies。
dev_dependencies:
  transmogrify: ^1.4.0


# 重写依赖包,会强制下载对应依赖包,并可以对该依赖包进行重写。
dependency_overrides:
  transmogrify: ^1.4.0


# Dart2开始需要添加该标签,声明该项目是基于dart的SDK哪个版本进行编译,随着dart平台的发展,可能在某个版本后不再向下兼容,所以这个标签约束了使用dart的版本
# 例,以下约束说明此项目仅适用于2.0到3.0的dart2 SDK编译。
environment:
  sdk: '>=2.0.0 <3.0.0'


# 可以将Dart2的可执行脚本引入到flutter之中,作为插件使用,但前提是这些脚本均可以在命令行正常调用。
executables:
  : 


# 指定生成发布包的位置
# 非必填
# 若不填写,则默认使用pub.dev站点进行发布,但若希望阻止发布,则需要声明为none。
# 同时此设置可以将flutter项目发布到自定义的服务器之中。
publish_to: none


#
# 项目中配置声明方式
# 用于在项目中添加资源、设置字体、配置插件参数等。
fluuter:
  # 实例1 添加资源
  assets:
      - images/park.jpg
  #设置字体,样式,可以通过声明family来设置字体分组
  fonts:
      - family: Schyler
        fonts:
          - asset: fonts/Schyler-Regular.ttf
          - asset: fonts/Schyler-Italic.ttf
            style: italic


      - family: Trajan Pro
        fonts:
      - asset: fonts/TrajanPro.ttf
      - asset: fonts/TrajanPro_Bold.ttf
        weight: 700


#
# 其他声明方式


# 实例1 定义常量
age: 22
boolitem: true
name: 'hello'


#实例2 定义数组
server:
    - aaaaaa
    - bbbbbb
    - dddddd


延伸阅读:

深度了解Flutter APP的构建流程_人生百年几今日,今日不为真可惜。-CSDN博客_flutter 构建号首先我们来看一下,用Android Studio打开一个新创建的flutter工程的工程结构:我们主要关心以下四部分:android 目录:android子工程,和普通android工程类似,包含app目录,gradle目录和gradle配置。ios目录:ios子工程lib目录:dart源文件,Flutter源码主要在这里pubspec.yaml文件:Flutter配置文件,添加dart包packages依赖和包名flutter作为一个跨平台开发框架,必然会合成到某一个壳工程,这里我们https://blog.csdn.net/huangbiao86/article/details/120694585

对于包,我们通常是指定版本区间,而很少直接指定特定版本,因为包升级变化很频繁,如果有其他的包直接或间接依赖这个包的其他版本时,就会经常发生冲突。

而对于运行环境,如果是团队多人协作的工程,建议将 Dart 与 Flutter 的 SDK 环境写死,统一团队的开发环境,避免因为跨 SDK 版本出现的 API 差异进而导致工程问题。

比如,在上面的示例中,我们可以将 Dart SDK 写死为 2.7.0,Flutter SDK 写死为2.0.0。

environment:
  sdk: 2.7.0
  
  flutter: 2.0.0

 对于dependencies中不同数据源,Dart会使用不同的方式进行管理,最终都会将远端的包全部下载到本地。比如:对于Git声明依赖的方式,Pub会clone git仓库;对于版本号的方式,Pub则会从pub.dartlang.ort下载包。如果还有其他的依赖包,比如pkg1还包含了pkg2包,Pub也会一并下载。

Pub在下载完所有的依赖包之后,Pub会在应用的更目录下创建.packages文件,并将依赖包名与系统缓存中的包文件路径进行映射,方便后期维护。

最后,Pub会自动创建pubspec.loc文件。pubspec.loc文件的作用就是类似IOS的Podfile.lock或者前端的package-lock.json文件,用于记录当前状态下实际安装的各个直接依赖,间接以来的包的具体来源和版本号。

比较活跃的第三方包的升级通常比较频繁,因此对于多人协作的 Flutter 应用来说,我们需要把 pubspec.lock 文件也一并提交到代码版本管理中,这样团队中的所有人在使用这个应用时安装的所有依赖都是完全一样的,以避免出现库函数找不到或者其他的依赖错误。

除了提供功能和代码维度的依赖之外,包还可以提供资源的依赖。如何资源依赖在上面pubspec.yaml已有介绍:目录文件配置如下
 

# 项目中配置声明方式
# 用于在项目中添加资源、设置字体、配置插件参数等。
flutter:
  uses-material-design: true
    # 实例1 添加资源
  assets:
        - images/park.jpg
        - images/lake.jpg
        - images/touxiang.jpg

原生工程如何找到Flutter module
有人在想pub上面的各种插件有些是需要调用原生功能,那么我们在pubspec.yaml引入之后,它又是如何被原生工程发现有啥如何被include到原生工程的呢?

那么这里就需要在介绍两个问题:.flutter-plugins 与 .flutter-plugins-dependencies文件,这两个文件是在flutter pub get之后,也就是pub在下载了第三方引入库之后自动生成的,下面看看这两个文件的主要内容:

.flutter-plugins

# This is a generated file; do not edit or check into version control.
connectivity=/Users/beason/Library/Flutter/flutter1.12.13/.pub-cache/hosted/pub.flutter-io.cn/connectivity-0.4.5+7/
image_picker_saver=/Users/beason/Library/Flutter/flutter1.12.13/.pub-cache/hosted/pub.flutter-io.cn/image_picker_saver-0.3.0/
message_core=/Users/beason/Projects/sfim/poc_lanyun/load_module/fs-base-ios-flutter-foundation/message_core/

.flutter-plugins-dependencies

{
    "_info":"// This is a generated file; do not edit or check into version control.",
    "dependencyGraph":[
        {
            "name":"connectivity",
            "dependencies":[

            ]
        },
        {
            "name":"image_picker_saver",
            "dependencies":[

            ]
        },
        {
            "name":"message_core",
            "dependencies":[

            ]
        }
    ]
}

.flutter-plugins 主要是记载了所有的插件名称以及插件缓存地址

.flutter-plugins-dependencies 主要记载了所有插件名称以及它们之间的相互依赖关系 ,这个文件在gradle 构建 flutter app / flutter module的时候会有用到,如果不熟悉建议看另一篇博文:深度了解Flutter APP的构建流程

注意:有人在新建了一个hello_flutter工程之后,pub get之后并没生成.flutter-plugins和.flutter-plugins-dependencies文件,那是因为这两个文件作用是gradle与pub之间的桥梁,如果插件/库里面没有包含有原生的相关的内容,是不会被加入到.flutter-plugins-dependencies和.flutter-plugins文件中的。

举例

好了讲到这里我们对flutter/dart是如何管理源码,版本,以及gradle是如何找到并且include flutter-plugin有了更深刻的认识,下面我们来简单介绍一下如何使用pub第三方库;

Pub官方库:https://pub.flutter-io.cn/

这里以官方date_format为例,介绍如何使用,首先使用pub库分为以下几个步骤:

在pub上找到date_format这个包(一般都有使用说明)
确定需要引入的版本,在pubspec.yaml中添加引入指定的date_format的版本
IDE会检测到配置文件的改动,需要重新get dependencies,或者手动在pubspec.yaml同目录下执行flutter pub get命令下载第三方库
加入了date_format库之后的pubspec.yaml文件:

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: 1.0.2
  date_format: 2.0.4

date_format插件下载完后我们就可以在dart文件中使用该插件了。

版本冲突怎么解决

如果项目依赖了 A , B 库,他们都依赖了一个 C ,但 C 的版本不同,可能会产生版本冲突。pub 会尝试找到符合所有依赖约束的版本号。如果找不到能匹配的版本,但 A ,B 库依赖 C 库的 API 是一样的,那么可以添加一个依赖覆盖来强制指定某一版本。

注:pub 是 Dart SDK 提供的一个包管理工具

dependencies:
 some_package:
 other_package:
dependency_overrides:
 url_launcher: '0.4.3' 


如果是 Android 平台的库依赖冲突,可以在 app 的 gradle 文件中强制指定版本

configurations.all {
    resolutionStrategy {
        force 'com.google.guava:guava:23.0-android'
    }
} 

注意: iOS 平台下 CocoaPods 不支持强制版本覆盖

从不同的依赖源添加依赖

The SDK source is used for any SDKs that are shipped along with packages, which may themselves be dependencies. Currently, Flutter is the only SDK that is supported.

通俗讲,就是 Flutter SDK 自带的库。打开我们 Flutter 的安装地址,进入flutter/packages可以看到各种包,如flutter,flutter_driver,flutter_test等。

➜  packages git:(stable) ✗ ls
analysis_options.yaml         flutter_localizations
flutter                       flutter_test
flutter_driver                flutter_tools
flutter_goldens               fuchsia_remote_debug_protocol
flutter_goldens_client
➜  packages git:(stable) ✗ pwd
/Users/xxx/flutter/packages 

在 Flutter 项目中写过测试的同学对上面几个依赖应该不陌生

dependencies:
 flutter:
 sdk: flutter # 来源于flutter sdk
dev_dependencies:
 flutter_test:
 sdk: flutter
 flutter_driver:
 sdk: flutter 


Hosted

A hosted package is one that can be downloaded from pub.dartlang.org (or another HTTP server that speaks the same API).

pub

dependencies:
 transmogrify: ^1.4.0 

自己的服务器

dependencies:
 transmogrify: ^1.4.0 
 transmogrify:
 hosted:
 name: transmogrify
 url: http://your-package-server.com
 version: ^1.4.0 

Git

dependencies:
 kittens:
 git: git://github.com/munificent/kittens.git 


指定分支

dependencies:
 kittens:
 url: git://github.com/munificent/kittens.git
 ref: some-branch 

pub 默认包目录在 git 仓库的根目录,如果要指定在别的位置,可以用 path 参数

dependencies:
 kittens:
 git:
 url: git://github.com/munificent/cats.git
 path: path/to/kittens 

本地路径

特别适用在一个人同时开发项目和依赖库的情况。因为修改依赖库的代码,在项目中就可以即时生效,有利于调试和提高效率。

dependencies:
 transmogrify:
 path: /Users/me/transmogrify # 也可以相对路径,相对路径以 pubspec.yml 文件为基准

依赖的分类

直接依赖和传递依赖

根据依赖与项目的关系,可以分为以下2类:

  • immediate dependency :项目中直接使用的依赖,即我们在 pubspec 中列出的依赖,包括 dependcies 和 dev_dependencies
  • transitive dependency :直接依赖所需的依赖, pub 会根据 pubspec 中列出的依赖自动为我们获取。

举个例子

比如我们项目依赖 A ,而 A 又依赖 B , B 又依赖 C 。那么 A 是我们项目的immediate dependency, B 和 C 就是transitive dependency

我们可以在命令行中输入命令flutter packages pub deps,查看项目的依赖树。 比如我们在项目中引入了一个支持网络缓存的图片库cached_network_image: ^0.5.0+1

flutter packages pub deps
Dart SDK 2.1.0-dev.9.4.flutter-f9ebf21297
Flutter SDK 1.0.1-pre.2
your_app_name 2.2.0+10 # 项目名称和版本
|-- cached_network_image 0.5.1 # 直接依赖
|   |-- flutter... # 直接依赖(因为在项目pubspec中也添加了)
|   '-- flutter_cache_manager 0.2.0+1 # 传递依赖
|       |-- flutter...
|       |-- http...
|       |-- path_provider...
|       |-- shared_preferences...
|       |-- synchronized 1.5.3
|       '-- uuid 1.0.3
|           |-- convert...
|           '-- crypto...
... 


常规依赖和dev依赖

根据依赖的作用范围,可以分为:

  • dependencies :常规依赖
  • dev dependencies :开发时所需依赖。它和常规依赖的区别是,项目依赖库中的 dev dependencies ,对于你的项目来说是不可见的。

举个例子

项目的 pubspec.yml 如下。如果 A 有一个 dev_dependencies 依赖 dev_C ,项目最终的依赖是 A , dev_B;不包括 dev_C。

dependencies:
 A:
dev_dependencies:
 dev_B: 


适用场景:如果你需要 import 到 lib 或者 bin 目录,那么选择 dependencies ; 如果你只需要 import 到 test , example 等,那么就选择 dev dependencies 。使用 dev dependencies 的好处是能让依赖树更小,从而使 pub 运行更快,能跟容易找到满足所有约束的包版本。

包管理

在获取一个新的依赖时,pub 会下载满足版本条件的_最新版本_,然后把版本信息添加到一个 lockfile 中。这个 lockfile 文件叫 pubspec.lock ,位于项目 pubspec.yml 的同级目录。它列出了项目的每个依赖(包括直接依赖和传递依赖)的版本信息。我们应该把这个 lockfile 添加到版本控制中,这样不论开发环境,生产环境都能确保使用了相同的依赖版本。

举个例子

项目的 pubspec.yml 文件包含如下依赖

...
dependencies:
 flutter:
 sdk: flutter
 cached_network_image: ^0.5.0+1

dev_dependencies:
 flutter_test:
 sdk: flutter
... 

结合上面提到知识,我们来看看 pubspec.lock 的内容。 lockfile 把所有依赖树打平,并根据首字母排序

cached_network_image:
    dependency: "direct main" # 直接依赖,常规依赖
    description:
      name: cached_network_image
      url: "https://pub.flutter-io.cn"
    source: hosted
    version: "0.5.1"
flutter: 
    dependency: "direct main" # 直接依赖,常规依赖
    description: flutter
    source: sdk


 

你可能感兴趣的:(flutter,flutter,android,android,studio)