ruby-gems-bundler

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Ruby Gems and Bundler

Ruby Gems 与 Bundler

Master Ruby's package management system with gems and Bundler. Learn to manage dependencies, create gems, and publish to RubyGems.
掌握基于gems和Bundler的Ruby包管理系统。学习如何管理依赖、创建gem并发布到RubyGems。

Bundler Basics

Bundler 基础

Gemfile

Gemfile

ruby
source 'https://rubygems.org'
ruby
source 'https://rubygems.org'

Ruby version

Ruby version

ruby '3.3.0'
ruby '3.3.0'

Production gems

Production gems

gem 'rails', '> 7.1' gem 'pg', '>= 1.1' gem 'puma', '> 6.0'
gem 'rails', '> 7.1' gem 'pg', '>= 1.1' gem 'puma', '> 6.0'

Development and test gems

Development and test gems

group :development, :test do gem 'rspec-rails' gem 'factory_bot_rails' gem 'faker' end
group :development, :test do gem 'rspec-rails' gem 'factory_bot_rails' gem 'faker' end

Development only

Development only

group :development do gem 'rubocop' gem 'rubocop-rails' end
group :development do gem 'rubocop' gem 'rubocop-rails' end

Test only

Test only

group :test do gem 'capybara' gem 'selenium-webdriver' end
group :test do gem 'capybara' gem 'selenium-webdriver' end

Git source

Git source

Local path (for development)

Local path (for development)

gem 'local_gem', path: '../local_gem'
gem 'local_gem', path: '../local_gem'

Specific branch

Specific branch

gem 'experimental_gem', git: 'https://github.com/user/repo.git', branch: 'develop'
gem 'experimental_gem', git: 'https://github.com/user/repo.git', branch: 'develop'

Require specific file or false to not auto-require

Require specific file or false to not auto-require

gem 'sidekiq', require: 'sidekiq/web' gem 'bootsnap', require: false
undefined
gem 'sidekiq', require: 'sidekiq/web' gem 'bootsnap', require: false
undefined

Version Constraints

版本约束

ruby
undefined
ruby
undefined

Exact version

Exact version

gem 'rails', '7.1.0'
gem 'rails', '7.1.0'

Pessimistic operator (allows patch updates)

Pessimistic operator (allows patch updates)

gem 'rails', '> 7.1.0' # >= 7.1.0 and < 7.2.0 gem 'rails', '> 7.1' # >= 7.1.0 and < 8.0.0
gem 'rails', '> 7.1.0' # >= 7.1.0 and < 7.2.0 gem 'rails', '> 7.1' # >= 7.1.0 and < 8.0.0

Greater than or equal

Greater than or equal

gem 'pg', '>= 1.1'
gem 'pg', '>= 1.1'

Range

Range

gem 'ruby-version', '>= 1.0', '< 2.0'
gem 'ruby-version', '>= 1.0', '< 2.0'

Multiple constraints

Multiple constraints

gem 'nokogiri', '>= 1.10', '< 2.0'
undefined
gem 'nokogiri', '>= 1.10', '< 2.0'
undefined

Bundler Commands

Bundler 命令

bash
undefined
bash
undefined

Install all gems from Gemfile

Install all gems from Gemfile

bundle install
bundle install

Install to specific path

Install to specific path

bundle install --path vendor/bundle
bundle install --path vendor/bundle

Update all gems

Update all gems

bundle update
bundle update

Update specific gem

Update specific gem

bundle update rails
bundle update rails

Check for outdated gems

Check for outdated gems

bundle outdated
bundle outdated

Show gem location

Show gem location

bundle show rails
bundle show rails

Execute command with bundled gems

Execute command with bundled gems

bundle exec rspec
bundle exec rspec

Open gem in editor

Open gem in editor

bundle open rails
bundle open rails

Check Gemfile syntax

Check Gemfile syntax

bundle check
bundle check

Remove unused gems

Remove unused gems

bundle clean
bundle clean

List all installed gems

List all installed gems

bundle list
bundle list

Show dependency tree

Show dependency tree

bundle viz
undefined
bundle viz
undefined

Gemfile.lock

Gemfile.lock

The
Gemfile.lock
file locks gem versions for consistent installations:
ruby
undefined
Gemfile.lock
文件用于锁定gem版本,确保所有安装环境的一致性:
ruby
undefined

Always commit Gemfile.lock to version control

Always commit Gemfile.lock to version control

This ensures all developers use same gem versions

This ensures all developers use same gem versions

Regenerate Gemfile.lock

Regenerate Gemfile.lock

rm Gemfile.lock bundle install
undefined
rm Gemfile.lock bundle install
undefined

Creating Gems

创建 Gem

Gem Structure

Gem 结构

bash
undefined
bash
undefined

Create new gem

Create new gem

bundle gem my_gem
bundle gem my_gem

Structure:

Structure:

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
undefined
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
undefined

Gemspec

Gemspec

ruby
undefined
ruby
undefined

my_gem.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 = ["Your Name"] spec.email = ["your.email@example.com"]
spec.summary = "Short summary of gem" spec.description = "Longer description of what gem does" 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"

Specify which files should be added to the 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"]

Runtime dependencies

spec.add_dependency "activesupport", "~> 7.0" spec.add_dependency "nokogiri", ">= 1.10"

Development dependencies

spec.add_development_dependency "rspec", "> 3.12" spec.add_development_dependency "rubocop", "> 1.50" end
undefined
require_relative 'lib/my_gem/version'
Gem::Specification.new do |spec| spec.name = "my_gem" spec.version = MyGem::VERSION spec.authors = ["Your Name"] spec.email = ["your.email@example.com"]
spec.summary = "Short summary of gem" spec.description = "Longer description of what gem does" 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"

Specify which files should be added to the 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"]

Runtime dependencies

spec.add_dependency "activesupport", "~> 7.0" spec.add_dependency "nokogiri", ">= 1.10"

Development dependencies

spec.add_development_dependency "rspec", "> 3.12" spec.add_development_dependency "rubocop", "> 1.50" end
undefined

Version File

版本文件

ruby
undefined
ruby
undefined

lib/my_gem/version.rb

lib/my_gem/version.rb

module MyGem VERSION = "0.1.0" end
undefined
module MyGem VERSION = "0.1.0" end
undefined

Main Library File

主库文件

ruby
undefined
ruby
undefined

lib/my_gem.rb

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
undefined
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
undefined

Building and Publishing

构建与发布

Build Gem

构建 Gem

bash
undefined
bash
undefined

Build gem locally

Build gem locally

gem build my_gem.gemspec
gem build my_gem.gemspec

This creates my_gem-0.1.0.gem

This creates my_gem-0.1.0.gem

Install locally for testing

Install locally for testing

gem install ./my_gem-0.1.0.gem
gem install ./my_gem-0.1.0.gem

Uninstall

Uninstall

gem uninstall my_gem
undefined
gem uninstall my_gem
undefined

Publish to RubyGems

发布到 RubyGems

bash
undefined
bash
undefined

First time setup (one-time)

First time setup (one-time)

gem push my_gem-0.1.0.gem
gem push my_gem-0.1.0.gem

You'll be prompted to log in

You'll be prompted to log in

For subsequent pushes

For subsequent pushes

gem push my_gem-0.2.0.gem
gem push my_gem-0.2.0.gem

Yank a version (removes from RubyGems)

Yank a version (removes from RubyGems)

gem yank my_gem -v 0.1.0
gem yank my_gem -v 0.1.0

Unyank a version

Unyank a version

gem unyank my_gem -v 0.1.0
undefined
gem unyank my_gem -v 0.1.0
undefined

Versioning

版本控制

ruby
undefined
ruby
undefined

Semantic Versioning: MAJOR.MINOR.PATCH

Semantic Versioning: MAJOR.MINOR.PATCH

1.0.0 -> 1.0.1 (patch)

1.0.0 -> 1.0.1 (patch)

1.0.1 -> 1.1.0 (minor)

1.0.1 -> 1.1.0 (minor)

1.1.0 -> 2.0.0 (major)

1.1.0 -> 2.0.0 (major)

lib/my_gem/version.rb

lib/my_gem/version.rb

module MyGem VERSION = "1.0.0" end
module MyGem VERSION = "1.0.0" end

Update version, then build and push:

Update version, then build and push:

1. Edit version.rb

1. Edit version.rb

2. gem build my_gem.gemspec

2. gem build my_gem.gemspec

3. gem push my_gem-1.0.0.gem

3. gem push my_gem-1.0.0.gem

undefined
undefined

RubyGems Commands

RubyGems 命令

bash
undefined
bash
undefined

List installed gems

List installed gems

gem list
gem list

Search for gems

Search for gems

gem search rails
gem search rails

Show gem info

Show gem info

gem info rails
gem info rails

List gem dependencies

List gem dependencies

gem dependency rails
gem dependency rails

Update all gems

Update all gems

gem update
gem update

Update specific gem

Update specific gem

gem update rails
gem update rails

Cleanup old versions

Cleanup old versions

gem cleanup
gem cleanup

Show gem environment

Show gem environment

gem env
gem env

Install specific version

Install specific version

gem install rails -v 7.1.0
gem install rails -v 7.1.0

Install without documentation (faster)

Install without documentation (faster)

gem install rails --no-document
gem install rails --no-document

Uninstall gem

Uninstall gem

gem uninstall rails
gem uninstall rails

Fetch gem but don't install

Fetch gem but don't install

gem fetch rails
undefined
gem fetch rails
undefined

Gem Groups

Gem 分组

ruby
undefined
ruby
undefined

Define groups

Define groups

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

Install without specific groups

Install without specific groups

bundle install --without production
bundle install --without production

Require specific groups

Require specific groups

Bundler.require(:default, :development)
undefined
Bundler.require(:default, :development)
undefined

Gem Sources

Gem 源

ruby
undefined
ruby
undefined

Primary source

Primary source

Additional sources

Additional sources

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

Git sources

Git sources

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'
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 shorthand

GitHub shorthand

gem 'my_gem', github: 'user/my_gem'
gem 'my_gem', github: 'user/my_gem'

Local path

Local path

gem 'my_gem', path: '../my_gem'
undefined
gem 'my_gem', path: '../my_gem'
undefined

Requiring Gems

引入 Gem

ruby
undefined
ruby
undefined

In code

In code

require 'my_gem'
require 'my_gem'

Bundler auto-requires gems based on Gemfile

Bundler auto-requires gems based on Gemfile

To disable auto-require:

To disable auto-require:

gem 'my_gem', require: false
gem 'my_gem', require: false

Then manually require where needed:

Then manually require where needed:

require 'my_gem'
require 'my_gem'

Require specific file

Require specific file

gem 'sidekiq', require: 'sidekiq/web'
undefined
gem 'sidekiq', require: 'sidekiq/web'
undefined

Platform-Specific Gems

特定平台 Gem

ruby
undefined
ruby
undefined

Only install on specific platforms

Only install on specific platforms

gem 'pg', platforms: :ruby gem 'sqlite3', platforms: [:mingw, :mswin, :x64_mingw]
gem 'pg', platforms: :ruby gem 'sqlite3', platforms: [:mingw, :mswin, :x64_mingw]

Multiple platforms

Multiple platforms

platforms :ruby do gem 'pg' gem 'nokogiri' end
platforms :jruby do gem 'activerecord-jdbc-adapter' end
undefined
platforms :ruby do gem 'pg' gem 'nokogiri' end
platforms :jruby do gem 'activerecord-jdbc-adapter' end
undefined

Private Gems

私有 Gem

Using Private Gem Server

使用私有 Gem 服务器

ruby
undefined
ruby
undefined

Gemfile

Gemfile

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

Using Git Credentials

使用 Git 凭证

bash
undefined
bash
undefined

.netrc file for private repos

.netrc file for private repos

machine github.com login your-username password your-token
undefined
machine github.com login your-username password your-token
undefined

Gem Development

Gem 开发

Using
bundle console

使用
bundle console

bash
undefined
bash
undefined

Open IRB with gem loaded

Open IRB with gem loaded

bin/console
bin/console

Or

Or

bundle console
undefined
bundle console
undefined

Running Tests

运行测试

bash
undefined
bash
undefined

Using Rake

Using Rake

rake spec
rake spec

Or directly

Or directly

bundle exec rspec
undefined
bundle exec rspec
undefined

Local Development

本地开发

ruby
undefined
ruby
undefined

In your app's Gemfile, point to local gem

In your app's Gemfile, point to local gem

gem 'my_gem', path: '../my_gem'
gem 'my_gem', path: '../my_gem'

Or use bundle config

Or use bundle config

bundle config local.my_gem ../my_gem
undefined
bundle config local.my_gem ../my_gem
undefined

Best Practices

最佳实践

  1. Always commit Gemfile.lock to version control
  2. Use pessimistic versioning (~>) for stability
  3. Keep gems updated but test thoroughly
  4. Use groups to separate dev/test/production gems
  5. Specify Ruby version in Gemfile for consistency
  6. Use bundle exec to ensure correct gem versions
  7. Document gem dependencies and why they're needed
  8. Test gems locally before publishing
  9. Follow semantic versioning for your gems
  10. Keep gemspecs clean and well-documented
  1. 始终将 Gemfile.lock 提交到版本控制系统
  2. 使用悲观版本约束(~>) 以保证稳定性
  3. 保持gem更新 但需进行充分测试
  4. 使用分组 区分开发/测试/生产环境的gem
  5. 在Gemfile中指定Ruby版本 确保一致性
  6. 使用bundle exec 以确保使用正确的gem版本
  7. 记录gem依赖 以及使用原因
  8. 发布前在本地测试gem
  9. 遵循语义化版本规范 管理你的gem版本
  10. 保持gemspec简洁且文档完善

Anti-Patterns

反模式

Don't commit vendor/bundle to git (use .gitignore) ❌ Don't use
require: false
unnecessarily
- adds manual work ❌ Don't specify exact versions unless absolutely necessary ❌ Don't push untested gem versions to RubyGems ❌ Don't include unnecessary files in gem packages ❌ Don't hardcode credentials in gemspec or Gemfile
不要将vendor/bundle提交到git(添加到.gitignore) ❌ 不要不必要地使用
require: false
- 会增加手动工作量 ❌ 除非绝对必要,否则不要指定精确版本不要将未测试的gem版本推送到RubyGems不要在gem包中包含不必要的文件不要在gemspec或Gemfile中硬编码凭证

Troubleshooting

故障排查

bash
undefined
bash
undefined

Clear bundler cache

Clear bundler cache

bundle clean --force
bundle clean --force

Regenerate Gemfile.lock

Regenerate Gemfile.lock

rm Gemfile.lock && bundle install
rm Gemfile.lock && bundle install

Check for gem conflicts

Check for gem conflicts

bundle exec gem dependency
bundle exec gem dependency

Verbose output

Verbose output

bundle install --verbose
bundle install --verbose

Show why a gem is needed

Show why a gem is needed

bundle show rails
bundle show rails

List all gem versions

List all gem versions

bundle list
undefined
bundle list
undefined

Related Skills

相关技能

  • ruby-oop - For structuring gem code
  • ruby-metaprogramming - Used in many gems
  • ruby-standard-library - Core Ruby functionality
  • ruby-oop - 用于构建gem代码结构
  • ruby-metaprogramming - 许多gem中会用到
  • ruby-standard-library - Ruby核心功能