Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Thành thạo Ruby Gems, Gemfile và Bundler: Hướng dẫn toàn diện

Ruby gem là gì?

Gem là package bạn download và cài đặt. Khi require gem đã cài, bạn thêm functionality cho chương trình Ruby.

Gem cho phép bạn:

  • Thêm tính năng login cho Rails app
  • Dễ dàng làm việc với service bên ngoài (như API)
  • Xây dựng web application

Đó chỉ vài ví dụ. Mỗi gem có mục tiêu riêng.

Tại sao dùng gem?

  • Cách chúng ta share library và tool trong Ruby
  • Cấu trúc file và format gem giúp dễ hiểu cách hoạt động
  • File specification (".spec") đi kèm gem mô tả dependency (gem khác cần thiết) để code có mọi thứ cần để chạy

Nhờ RubyGems, chúng ta có hệ sinh thái library hữu ích chỉ một gem install!

Danh sách gem cần cho project (non-gem) có thể liệt kê trong file đặc biệt "Gemfile" để tự động cài bởi Bundler. Cả hai covered sau trong guide.

Ví dụ gem nào?

  • Rails và các component (ActiveRecord, ActiveSupport, v.v.) phân phối như Ruby gem
  • Pry, alternative mạnh cho irb
  • Nokogiri, parser XML & HTML phổ biến

Đa số gem là Ruby code thuần.

Một ít gem bao gồm C extension cho performance.

Extension build tự động khi cài gem. Một số case, bạn cần cài thủ công software không do RubyGems quản lý.

Bây giờ:

Hãy học thêm về gem bằng cách build gem riêng và xem file tạo nên gem.

Cách Build RubyGem

Bạn chuẩn bị file cho gem mới chạy bundle gem <name>.

Ví dụ:

 bundle gem awesome_gem 

Một Gem gồm cấu trúc sau:

 ├── awesome_gem.gemspec
├── bin
│   ├── console
│   └── setup
├── Gemfile
├── lib
│   ├── awesome_gem
│   │   └── version.rb
│   └── awesome_gem.rb
├── Rakefile
├── README.md
└── test
    ├── awesome_gem_test.rb
    └── test_helper.rb 

File .gemspec là nơi bạn tìm mọi thông tin về gem.

Bao gồm:

  • Tên gem
  • Tóm tắt gem (mô tả ngắn)
  • Tên tác giả
  • Danh sách dependency
  • Danh sách file include trong gem
  • Tùy chọn: email tác giả, URL project (homepage), executables, c extensions, mô tả dài.

Version gem định nghĩa là constant trong lib/<gem_name>/version.rb.

Ví dụ gemspec:

 Gem::Specification.new do |spec|
  spec.name = "awesome_gem"
  spec.version = AwesomeGem::VERSION
  spec.authors = ["Jesus Castello"]
  spec.summary = "Example gem for article about Ruby gems"
  spec.files = Dir['**/**'].grep_v(/.gem$/)
  spec.require_paths = ["lib"]
  spec.add_development_dependency "bundler", "~> 1.16"
  spec.add_development_dependency "rake", "~> 10.0"
  spec.add_development_dependency "minitest", "~> 5.0"
end 

Mảng require_paths là nơi Ruby tìm file gem khi require. Cho phép code dưới lib/<gem_name>/ và require bằng require "<gem_name>/<file_name>".

Ví dụ:

File lib/awesome_gem/parser.rb require như require "awesome_gem/parser" từ bất kỳ đâu trong gem.

Phần lớn require ở lib/<gem_name>.rb (file duy nhất ở root /lib).

Đó là file load khi bạn require gem!

Tiếp:

Dòng add_development_dependency định nghĩa gem dùng khi development.

Gem như minitest, RSpec, pry.

Trong khi add_dependency định nghĩa gem dùng như phần code của bạn.

Khi đã đổi summary và description từ giá trị mặc định… bạn load irb session với gem dùng bin/console do bundle gem tạo.

Ví dụ:

 $ bin/console
irb(main):001:0>
irb(main):002:0>
irb(main):003:0> AwesomeGem
=> AwesomeGem
irb(main):004:0>
irb(main):005:0> AwesomeGem::VERSION
=> "0.1.0" 

Sau đó package gem dùng gem build <name>.gemspec và publish lên rubygems.org dùng gem push.

Bundler là gì?

Khi học Ruby gem bạn cũng đọc về Bundler.

Nhưng Bundler chính xác là gì?

Bundler là tool cho dependency management.

RubyGems không xử lý rồi sao?

À, nó xử lý… nhưng chỉ cho gem bản thân.

Ruby app thường không build as gem, nên không có feature này.

Đó là lý do Bundler tồn tại!

Hiểu Gemfile

Bạn thấy file Gemfile?

Đó là nơi viết gem bạn muốn dùng cho Ruby application của bạn.

Các gem này load cho bạn không cần require.

Gemfile trông như sau:

 ruby '2.5.0'
gem 'rails', '~> 5.2.1'
gem 'sqlite3'
gem 'puma', '~> 3.11'
gem 'bootsnap', '>= 1.1.0', require: false 

Bundler (và RubyGems từ version 2.0) đọc file này và cài version gem yêu cầu.

Đây là thứ bạn thấy chạy bundle install:

 Using turbolinks-source 5.1.0
Using turbolinks 5.1.1
Using uglifier 4.1.18
Using web-console 3.6.2
Bundle complete! 18 Gemfile dependencies, 78 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed. 

Bây giờ:

Các symbol (như ~>) dùng khi khai báo version gem trong Gemfile là gì?

Chúng cho phép yêu cầu một dải version.

Bạn nói: "Muốn version >= 1.2, nhưng < 2.0".

Trông như:

 gem 'puma', '~> 1.2' 

~> là shortcut cho dải này:

 gem 'puma', '>= 1.2', '< 2.0' 

Trường hợp ~> 5.2.1, nghĩa là chính xác này:

 '>= 5.2.1', '< 5.3' 

Version number càng cụ thể thì dải version càng hạn chế.

Gemfile Options & Gemfile.lock

Bạn có vài option khi require gem trong Gemfile.

Ví dụ:

Bạn muốn pull gem từ source khác, như GitHub.

Này hữu ích khi cần version mới nhất project, chưa release trên rubygems.org.

Ví dụ:

 gem "rails", git: "git@github.com:rails/rails.git" 

Bạn truyền option branch dùng code từ branch không phải master.

Như sau:

 gem "awesome_print", git: "git@github.com:awesome-print/awesome_print.git", branch: "v2" 

Option khác là require: false.

Làm gì?

Báo Bundler không auto-require gem. Nghĩa là bạn phải require trong code khi cần.

Dùng cho gem giới hạn scope.

Ví dụ:

Gem dùng trong rake task cụ thể, không dùng trong Rails controller & model. Lợi ích: tiết kiệm memory vì chỉ load gem khi cần.

Bạn cũng group gem theo environment.

Nghĩa là gem chỉ cài và load development (như capybara & pry).

Cuối cùng, bundler tạo Gemfile.lock.

Khác biệt?

Gemfile.lock tự động generate và nói chính xác version nào của mọi gem được cài.

Bundler cài version này nên khi deploy production, hoặc share project với dev khác, mọi người làm việc với identical gem set.

Lệnh Gem & Bundler hữu ích

Command Description
gem list Liệt kê tất cả gem đã cài. Chấp nhận argument filter theo tên (ví dụ: gem list active)
gem which <name> Cho đường dẫn gem được cài.
gem search <name> Tìm gem từ source cấu hình (mặc định: rubygems.org). Nhận regex (ví dụ: gem search "\Aawesome_").
gem env Hiển thị info môi trường gem (version, paths, config).
gem install <name> -v <version> Cài version gem cụ thể (ví dụ: gem install sinatra -v 2.0.0).
bundle viz Tạo visualization dependency graph project hiện tại.
bundle show Hiển thị info gem cụ thể cài qua bundler. Phải trong folder có Gemfile.
bundle outdated Hiển thị gem outdated trong project. Dùng option --groups group chúng.
bundle console Chạy irb session với gem từ Gemfile project hiện tại.

Tóm tắt

Bạn đã học về RubyGems, hệ thống package cho Ruby. Cũng học cấu trúc gem, Gemfile, Bundler và khác biệt Gemfile vs Gemfile.lock.

Hy vọng hữu ích!

Hãy chia sẻ bài viết, đăng ký newsletter nếu chưa (9000+ Ruby developer!) và check sách Ruby của tôi.

Cảm ơn đã đọc và ngày tốt lành 🙂