Ruby包管理与BundlerSkill ruby-gems-bundler

Ruby Gems和Bundler是Ruby语言的包管理系统,用于管理依赖、创建和发布gems,提升开发效率和项目维护。关键词:Ruby, Gems, Bundler, 依赖管理, 包管理, RubyGems。

后端开发 0 次安装 0 次浏览 更新于 3/25/2026

名称: ruby-gems-bundler 用户可调用: false 描述: 用于处理Ruby gems、使用Bundler进行依赖管理、创建gemspecs,以及将gems发布到RubyGems。 允许的工具:

  • Bash
  • 读取
  • 写入
  • 编辑

Ruby Gems 和 Bundler

掌握Ruby的包管理系统,包括gems和Bundler。学习管理依赖、创建gems并发布到RubyGems。

Bundler 基础

Gemfile

source 'https://rubygems.org'

# Ruby 版本
ruby '3.3.0'

# 生产环境 gems
gem 'rails', '~> 7.1'
gem 'pg', '>= 1.1'
gem 'puma', '~> 6.0'

# 开发和测试环境 gems
group :development, :test do
  gem 'rspec-rails'
  gem 'factory_bot_rails'
  gem 'faker'
end

# 仅开发环境
group :development do
  gem 'rubocop'
  gem 'rubocop-rails'
end

# 仅测试环境
group :test do
  gem 'capybara'
  gem 'selenium-webdriver'
end

# Git 源
gem 'my_gem', git: 'https://github.com/user/my_gem.git'

# 本地路径(用于开发)
gem 'local_gem', path: '../local_gem'

# 特定分支
gem 'experimental_gem', git: 'https://github.com/user/repo.git', branch: 'develop'

# 指定要求文件或false以不自动要求
gem 'sidekiq', require: 'sidekiq/web'
gem 'bootsnap', require: false

版本约束

# 精确版本
gem 'rails', '7.1.0'

# 悲观运算符(允许补丁更新)
gem 'rails', '~> 7.1.0'  # >= 7.1.0 且 < 7.2.0
gem 'rails', '~> 7.1'    # >= 7.1.0 且 < 8.0.0

# 大于或等于
gem 'pg', '>= 1.1'

# 范围
gem 'ruby-version', '>= 1.0', '< 2.0'

# 多个约束
gem 'nokogiri', '>= 1.10', '< 2.0'

Bundler 命令

# 从Gemfile安装所有gems
bundle install

# 安装到特定路径
bundle install --path vendor/bundle

# 更新所有gems
bundle update

# 更新特定gem
bundle update rails

# 检查过时的gems
bundle outdated

# 显示gem位置
bundle show rails

# 使用bundled gems执行命令
bundle exec rspec

# 在编辑器中打开gem
bundle open rails

# 检查Gemfile语法
bundle check

# 移除未使用的gems
bundle clean

# 列出所有已安装的gems
bundle list

# 显示依赖树
bundle viz

Gemfile.lock

Gemfile.lock 文件锁定gem版本以确保一致性安装:

# 始终将Gemfile.lock提交到版本控制
# 这确保所有开发者使用相同的gem版本

# 重新生成Gemfile.lock
rm Gemfile.lock
bundle install

创建 Gems

Gem 结构

# 创建新gem
bundle gem my_gem

# 结构:
my_gem/
├── lib/
│   ├── my_gem/
│   │   └── version.rb
│   └── my_gem.rb
├── spec/
│   ├── my_gem_spec.rb
│   └── spec_helper.rb
├── bin/
│   ├── console
│   └── setup
├── .gitignore
├── Gemfile
├── LICENSE.txt
├── my_gem.gemspec
├── Rakefile
└── README.md

Gemspec

# my_gem.gemspec
require_relative 'lib/my_gem/version'

Gem::Specification.new do |spec|
  spec.name          = "my_gem"
  spec.version       = MyGem::VERSION
  spec.authors       = ["您的名字"]
  spec.email         = ["您的邮箱@example.com"]

  spec.summary       = "gem的简短摘要"
  spec.description   = "gem功能的较长描述"
  spec.homepage      = "https://github.com/username/my_gem"
  spec.license       = "MIT"

  spec.required_ruby_version = ">= 3.0.0"

  spec.metadata["homepage_uri"] = spec.homepage
  spec.metadata["source_code_uri"] = "https://github.com/username/my_gem"
  spec.metadata["changelog_uri"] = "https://github.com/username/my_gem/CHANGELOG.md"

  # 指定应添加到gem的文件
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
    `git ls-files -z`.split("\x0").reject do |f|
      f.match(%r{\A(?:test|spec|features)/})
    end
  end

  spec.bindir        = "exe"
  spec.executables   = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
  spec.require_paths = ["lib"]

  # 运行时依赖
  spec.add_dependency "activesupport", "~> 7.0"
  spec.add_dependency "nokogiri", ">= 1.10"

  # 开发依赖
  spec.add_development_dependency "rspec", "~> 3.12"
  spec.add_development_dependency "rubocop", "~> 1.50"
end

版本文件

# lib/my_gem/version.rb
module MyGem
  VERSION = "0.1.0"
end

主库文件

# lib/my_gem.rb
require_relative "my_gem/version"
require_relative "my_gem/core"
require_relative "my_gem/helpers"

module MyGem
  class Error < StandardError; end

  def self.configure
    yield configuration
  end

  def self.configuration
    @configuration ||= Configuration.new
  end

  class Configuration
    attr_accessor :api_key, :timeout

    def initialize
      @api_key = nil
      @timeout = 30
    end
  end
end

构建和发布

构建 Gem

# 本地构建gem
gem build my_gem.gemspec

# 这会创建 my_gem-0.1.0.gem

# 本地安装以测试
gem install ./my_gem-0.1.0.gem

# 卸载
gem uninstall my_gem

发布到 RubyGems

# 首次设置(一次性)
gem push my_gem-0.1.0.gem
# 您将被提示登录

# 后续推送
gem push my_gem-0.2.0.gem

# 撤回版本(从RubyGems移除)
gem yank my_gem -v 0.1.0

# 取消撤回版本
gem unyank my_gem -v 0.1.0

版本控制

# 语义版本控制:主版本.次版本.补丁版本
# 1.0.0 -> 1.0.1 (补丁)
# 1.0.1 -> 1.1.0 (次版本)
# 1.1.0 -> 2.0.0 (主版本)

# lib/my_gem/version.rb
module MyGem
  VERSION = "1.0.0"
end

# 更新版本,然后构建和推送:
# 1. 编辑version.rb
# 2. gem build my_gem.gemspec
# 3. gem push my_gem-1.0.0.gem

RubyGems 命令

# 列出已安装的gems
gem list

# 搜索gems
gem search rails

# 显示gem信息
gem info rails

# 列出gem依赖
gem dependency rails

# 更新所有gems
gem update

# 更新特定gem
gem update rails

# 清理旧版本
gem cleanup

# 显示gem环境
gem env

# 安装特定版本
gem install rails -v 7.1.0

# 安装时不包含文档(更快)
gem install rails --no-document

# 卸载gem
gem uninstall rails

# 获取gem但不安装
gem fetch rails

Gem 分组

# 定义分组
group :development do
  gem 'pry'
end

group :test do
  gem 'rspec'
end

group :development, :test do
  gem 'factory_bot'
end

# 安装时不包含特定分组
bundle install --without production

# 要求特定分组
Bundler.require(:default, :development)

Gem 源

# 主要源
source 'https://rubygems.org'

# 附加源
source 'https://gems.example.com' do
  gem 'private_gem'
end

# Git 源
gem 'my_gem', git: 'https://github.com/user/my_gem.git'
gem 'my_gem', git: 'https://github.com/user/my_gem.git', tag: 'v1.0'
gem 'my_gem', git: 'https://github.com/user/my_gem.git', branch: 'main'
gem 'my_gem', git: 'https://github.com/user/my_gem.git', ref: 'abc123'

# GitHub 简写
gem 'my_gem', github: 'user/my_gem'

# 本地路径
gem 'my_gem', path: '../my_gem'

要求 Gems

# 在代码中
require 'my_gem'

# Bundler 根据Gemfile自动要求gems
# 禁用自动要求:
gem 'my_gem', require: false

# 然后在需要时手动要求:
require 'my_gem'

# 要求特定文件
gem 'sidekiq', require: 'sidekiq/web'

平台特定 Gems

# 仅安装在特定平台
gem 'pg', platforms: :ruby
gem 'sqlite3', platforms: [:mingw, :mswin, :x64_mingw]

# 多个平台
platforms :ruby do
  gem 'pg'
  gem 'nokogiri'
end

platforms :jruby do
  gem 'activerecord-jdbc-adapter'
end

私有 Gems

使用私有 Gem 服务器

# Gemfile
source 'https://rubygems.org'

source 'https://gems.mycompany.com' do
  gem 'private_gem'
end

使用 Git 凭证

# .netrc 文件用于私有仓库
machine github.com
  login 您的用户名
  password 您的令牌

Gem 开发

使用 bundle console

# 打开IRB并加载gem
bin/console

# 或
bundle console

运行测试

# 使用Rake
rake spec

# 或直接
bundle exec rspec

本地开发

# 在您的应用的Gemfile中,指向本地gem
gem 'my_gem', path: '../my_gem'

# 或使用bundle config
bundle config local.my_gem ../my_gem

最佳实践

  1. 始终将Gemfile.lock提交到版本控制
  2. 使用悲观版本控制(~>)以提高稳定性
  3. 保持gems更新但充分测试
  4. 使用分组来分离开发/测试/生产环境gems
  5. 在Gemfile中指定Ruby版本以确保一致性
  6. 使用bundle exec以确保正确的gem版本
  7. 记录gem依赖及其必要性
  8. 发布前在本地测试gems
  9. 遵循语义版本控制
  10. 保持gemspecs清晰且文档齐全

反模式

不要将vendor/bundle提交到git(使用.gitignore)不要不必要地使用require: false——增加手动工作除非绝对必要,不要指定精确版本不要将未测试的gem版本推送到RubyGems不要在gem包中包含不必要的文件不要在gemspec或Gemfile中硬编码凭证

故障排除

# 清除bundler缓存
bundle clean --force

# 重新生成Gemfile.lock
rm Gemfile.lock && bundle install

# 检查gem冲突
bundle exec gem dependency

# 详细输出
bundle install --verbose

# 显示为何需要某个gem
bundle show rails

# 列出所有gem版本
bundle list

相关技能

  • ruby-oop - 用于结构gem代码
  • ruby-metaprogramming - 在许多gems中使用
  • ruby-standard-library - 核心Ruby功能