Pub 高级特性 #

概述 #

本章介绍 Pub 的高级特性,帮助你更高效地管理 Dart/Flutter 项目,解决复杂场景下的问题。

私有仓库 #

为什么需要私有仓库? #

  • 保护内部代码
  • 加速依赖下载
  • 控制包版本
  • 满足合规要求

搭建私有仓库 #

1. unpub #

unpub 是一个开源的私有仓库实现:

bash
# 安装 unpub
dart pub global activate unpub

# 启动服务(需要 MongoDB)
unpub --database mongodb://localhost:27017/dart_pub

# 自定义端口
unpub --port 8080 --database mongodb://localhost:27017/dart_pub

2. pub_server #

bash
# 安装 pub_server
dart pub global activate pub_server

# 启动服务
pub_server --port 8080 /path/to/packages

3. 云服务 #

使用云服务搭建:

  • Google Cloud Storage
  • AWS S3
  • Azure Blob Storage

配置私有仓库 #

发布到私有仓库 #

bash
# 发布到私有仓库
dart pub publish --server=https://my-private-repo.com

从私有仓库安装 #

yaml
# pubspec.yaml
dependencies:
  my_private_package:
    hosted:
      name: my_private_package
      url: https://my-private-repo.com
    version: ^1.0.0

认证配置 #

添加认证令牌 #

bash
# 添加令牌
dart pub token add https://my-private-repo.com

# 输入令牌
# Enter secret token: your-secret-token

环境变量方式 #

bash
# 设置环境变量
export PUB_TOKEN=your-secret-token

# 或在 CI 中使用
# GitHub Actions
env:
  PUB_TOKEN: ${{ secrets.PUB_TOKEN }}

管理令牌 #

bash
# 列出所有令牌
dart pub token list

# 删除令牌
dart pub token remove https://my-private-repo.com

依赖覆盖 #

使用场景 #

  • 调试依赖问题
  • 测试新版本
  • 使用本地开发版本
  • 解决版本冲突

覆盖语法 #

yaml
# pubspec.yaml
dependency_overrides:
  # 覆盖版本
  http: 1.1.0

  # 覆盖为 Git 依赖
  my_package:
    git:
      url: https://github.com/user/repo.git
      ref: main

  # 覆盖为本地依赖
  my_local_package:
    path: ../my_local_package

多重覆盖 #

yaml
dependency_overrides:
  http: 1.1.0
  path: 1.9.0
  my_package:
    path: ../my_package

注意事项 #

  • 仅用于开发和测试
  • 不要提交到生产环境
  • 发布包时会忽略 dependency_overrides

缓存管理 #

缓存目录 #

bash
# 查看缓存目录
dart pub cache dir
# /Users/username/.pub-cache

缓存结构 #

text
.pub-cache/
├── hosted/              # pub.dev 包
│   └── pub.dev/
│       ├── http-1.1.0/
│       └── path-1.8.3/
├── git/                 # Git 依赖
│   └── github.com-user-repo-hash/
├── global_packages/     # 全局包
└── bin/                 # 全局可执行文件

缓存操作 #

bash
# 清理所有缓存
dart pub cache clean

# 清理特定包
dart pub cache clean http

# 修复缓存
dart pub cache repair

自定义缓存目录 #

bash
# 设置缓存目录
export PUB_CACHE=/custom/cache/path

# 永久配置
echo 'export PUB_CACHE=/custom/cache/path' >> ~/.zshrc

离线模式 #

bash
# 使用离线模式
dart pub get --offline

# 预下载所有依赖
dart pub get

Monorepo 支持 #

什么是 Monorepo? #

Monorepo 是将多个相关项目放在同一个仓库中的开发模式。

项目结构 #

text
my_monorepo/
├── packages/
│   ├── core/
│   │   ├── pubspec.yaml
│   │   └── lib/
│   ├── utils/
│   │   ├── pubspec.yaml
│   │   └── lib/
│   └── api/
│       ├── pubspec.yaml
│       └── lib/
├── apps/
│   ├── web/
│   │   ├── pubspec.yaml
│   │   └── lib/
│   └── mobile/
│       ├── pubspec.yaml
│       └── lib/
└── melos.yaml

使用 melos 管理 #

melos 是 Dart/Flutter 的 Monorepo 管理工具:

安装 melos #

bash
# 安装 melos
dart pub global activate melos

# 或使用 Flutter
flutter pub global activate melos

配置 melos.yaml #

yaml
# melos.yaml
name: my_monorepo

packages:
  - 'packages/**'
  - 'apps/**'

scripts:
  # 分析所有包
  analyze:
    run: dart analyze .
    exec:
      concurrency: 5

  # 运行所有测试
  test:
    run: dart test
    exec:
      concurrency: 1

  # 获取所有依赖
  bootstrap:
    run: dart pub get
    exec:
      concurrency: 5

常用命令 #

bash
# 初始化
melos bootstrap

# 分析所有包
melos analyze

# 运行所有测试
melos test

# 格式化代码
melos format

# 发布所有包
melos publish

包间依赖 #

yaml
# packages/api/pubspec.yaml
dependencies:
  core:
    path: ../core
  utils:
    path: ../utils

CI/CD 集成 #

GitHub Actions #

基础配置 #

yaml
# .github/workflows/ci.yml
name: Dart CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - uses: dart-lang/setup-dart@v1
        with:
          sdk: stable

      - name: Install dependencies
        run: dart pub get

      - name: Analyze
        run: dart analyze

      - name: Format
        run: dart format --output=none --set-exit-if-changed .

      - name: Test
        run: dart test

使用缓存 #

yaml
# .github/workflows/ci.yml
jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - uses: dart-lang/setup-dart@v1
        with:
          sdk: stable

      - name: Cache Pub dependencies
        uses: actions/cache@v3
        with:
          path: |
            ~/.pub-cache
            .dart_tool
          key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
          restore-keys: |
            ${{ runner.os }}-pub-

      - name: Install dependencies
        run: dart pub get

      - name: Test
        run: dart test

发布包 #

yaml
# .github/workflows/publish.yml
name: Publish to pub.dev

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - uses: dart-lang/setup-dart@v1
        with:
          sdk: stable

      - name: Install dependencies
        run: dart pub get

      - name: Test
        run: dart test

      - name: Publish
        run: dart pub publish --force
        env:
          PUB_TOKEN: ${{ secrets.PUB_TOKEN }}

GitLab CI #

yaml
# .gitlab-ci.yml
stages:
  - test
  - publish

test:
  stage: test
  image: dart:stable
  script:
    - dart pub get
    - dart analyze
    - dart test

publish:
  stage: publish
  image: dart:stable
  script:
    - dart pub get
    - dart pub publish --force
  only:
    - tags
  variables:
    PUB_TOKEN: $PUB_TOKEN

CircleCI #

yaml
# .circleci/config.yml
version: 2.1

jobs:
  build:
    docker:
      - image: dart:stable
    steps:
      - checkout
      - run:
          name: Install dependencies
          command: dart pub get
      - run:
          name: Analyze
          command: dart analyze
      - run:
          name: Test
          command: dart test

workflows:
  version: 2
  build-test:
    jobs:
      - build

脚本运行 #

定义脚本 #

yaml
# pubspec.yaml
executables:
  my_app: main
  my_tool: tool

运行脚本 #

bash
# 运行默认入口
dart run

# 运行特定文件
dart run bin/main.dart

# 运行定义的可执行文件
dart run my_app

# 传递参数
dart run my_app --verbose

开发脚本 #

dart
// tool/generate.dart
import 'dart:io';

void main(List<String> args) {
  print('Generating code...');
  // 脚本逻辑
}
bash
# 运行开发脚本
dart run tool/generate.dart

构建和代码生成 #

build_runner #

build_runner 是 Dart 的代码生成工具:

yaml
# pubspec.yaml
dev_dependencies:
  build_runner: ^2.4.0
  json_serializable: ^6.7.0
bash
# 生成代码
dart run build_runner build

# 监听变化
dart run build_runner watch

# 清理生成文件
dart run build_runner clean

自定义构建脚本 #

dart
// tool/build.dart
import 'dart:io';

void main() async {
  // 运行测试
  await Process.run('dart', ['test']);

  // 生成文档
  await Process.run('dart', ['doc', '.']);

  // 构建产物
  await Process.run('dart', ['compile', 'exe', 'bin/main.dart']);
}

性能优化 #

加速依赖获取 #

bash
# 使用镜像源
export PUB_HOSTED_URL=https://pub.flutter-io.cn

# 使用离线模式
dart pub get --offline

# 使用缓存
# 确保 CI 缓存 .pub-cache 和 .dart_tool

减少依赖数量 #

bash
# 查看依赖树
dart pub deps

# 识别未使用的依赖
# 手动检查 import 语句

优化缓存 #

bash
# 定期清理缓存
dart pub cache clean

# 仅清理特定包
dart pub cache clean unused_package

故障排除 #

常见问题 #

1. 依赖解析失败 #

bash
# 详细输出
dart pub get --verbose

# 清理并重新获取
rm -rf .dart_tool pubspec.lock
dart pub get

2. 网络问题 #

bash
# 使用镜像源
export PUB_HOSTED_URL=https://pub.flutter-io.cn

# 使用代理
export HTTP_PROXY=http://proxy:8080
export HTTPS_PROXY=http://proxy:8080

3. 缓存损坏 #

bash
# 修复缓存
dart pub cache repair

# 或完全清理
dart pub cache clean
dart pub get

4. 版本冲突 #

bash
# 查看依赖树
dart pub deps

# 使用依赖覆盖
dependency_overrides:
  conflicting_package: ^2.0.0

调试技巧 #

bash
# 详细日志
dart pub get --verbose

# 查看依赖树
dart pub deps --style=tree

# 检查过时依赖
dart pub outdated

# 查看缓存
dart pub cache dir

最佳实践 #

1. 使用版本约束 #

yaml
# ✅ 推荐
dependencies:
  http: ^1.0.0

# ❌ 不推荐
dependencies:
  http: any

2. 提交 pubspec.lock #

bash
# 应用项目
git add pubspec.lock

# 库项目(可选)
# 提交可以确保 CI 使用相同版本

3. 定期更新依赖 #

bash
# 每周或每月检查更新
dart pub outdated
dart pub upgrade

4. 使用 CI/CD #

自动化测试和发布流程。

5. 使用镜像源 #

在中国大陆使用镜像源加速下载。

6. 管理全局包 #

bash
# 列出全局包
dart pub global list

# 清理不需要的全局包
dart pub global deactivate unused_package

7. 使用 melos 管理 Monorepo #

对于多包项目,使用 melos 简化管理。

8. 编写自定义脚本 #

将常用操作封装为脚本。

总结 #

Pub 提供了丰富的功能来管理 Dart/Flutter 项目:

  • 私有仓库:保护内部代码,加速下载
  • 依赖覆盖:调试和测试特定版本
  • 缓存管理:优化性能,支持离线
  • Monorepo:管理多包项目
  • CI/CD:自动化测试和发布
  • 脚本运行:简化开发流程

掌握这些高级特性,可以让你更高效地开发和维护 Dart/Flutter 项目。

附录 #

常用命令速查 #

bash
# 依赖管理
dart pub get              # 获取依赖
dart pub add http         # 添加依赖
dart pub remove http      # 移除依赖
dart pub upgrade          # 升级依赖
dart pub outdated         # 检查过时依赖
dart pub deps             # 查看依赖树

# 缓存管理
dart pub cache dir        # 查看缓存目录
dart pub cache clean      # 清理缓存
dart pub cache repair     # 修复缓存

# 全局包
dart pub global activate package    # 激活全局包
dart pub global list                # 列出全局包
dart pub global deactivate package  # 停用全局包

# 发布
dart pub publish --dry-run  # 干运行
dart pub publish            # 发布包

# 令牌管理
dart pub token add url      # 添加令牌
dart pub token list         # 列出令牌
dart pub token remove url   # 删除令牌

环境变量 #

变量 描述
PUB_HOSTED_URL Pub 仓库镜像地址
PUB_CACHE 缓存目录
PUB_TOKEN 认证令牌
HTTP_PROXY HTTP 代理
HTTPS_PROXY HTTPS 代理
最后更新:2026-03-28