Sự khác biệt giữa Gemfile và Gemfile.lock trong Ruby on Rails


Câu trả lời:


159

Đây Gemfilelà nơi bạn chỉ định loại đá quý nào bạn muốn sử dụng và cho phép bạn chỉ định phiên bản nào.

Các Gemfile.locktập tin là nơi Bundler ghi lại phiên bản chính xác mà đã được cài đặt. Theo cách này, khi cùng một thư viện / dự án được tải trên một máy khác, việc chạy bundle installsẽ xem xét Gemfile.lockvà cài đặt các phiên bản chính xác, thay vì chỉ sử dụng Gemfilevà cài đặt các phiên bản gần đây nhất. (Chạy các phiên bản khác nhau trên các máy khác nhau có thể dẫn đến các thử nghiệm bị hỏng, v.v.) Bạn không bao giờ phải chỉnh sửa trực tiếp tệp khóa.

Kiểm tra Mục đích và Cơ sở lý luận của Bundler , cụ thể là phần Kiểm tra mã của bạn thành Kiểm soát phiên bản.


2
Đó là cách nó nên làm việc - nhưng dường như Gemfile.lockbao gồm các phiên bản 'mở' trong một số trường hợp (ví dụ như rails (4.0.0)đòi hỏi bundler (>= 1.3.0, < 2.0)), gây ra vấn đề. Bất cứ ý tưởng làm thế nào để tránh những phụ thuộc 'mở'?
Guillermo Grau

157

Thông thường chúng ta viết các phụ thuộc trong Gemfile là:

gem "nokogiri", "~> 1.4.4"
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'uglifier', '>= 1.2.3'
..

Về cơ bản, bạn nói: " Tôi muốn nokogiri miễn là nó lớn hơn phiên bản 1.4.4 ", v.v ... Bây giờ giả sử rằng tôi đã thiết lập Gemfile 8 tháng trước và tôi đã thiết lập thành công ứng dụng của mình với yêu cầu này. 8 tháng trước phiên bản nokogiri là 1.4.4 . Các ứng dụng rails của tôi đã chạy hoàn hảo mà không gặp vấn đề gì với phiên bản này.

Bây giờ nghĩ rằng tôi đang cố gắng xây dựng với cùng Gemfile. Nhưng nếu chúng ta nhìn vào các phiên bản nokogiri, chúng ta thấy rằng phiên bản ổn định hiện tại đã thay đổi thành 1.4.9 . Điều đó có nghĩa là nếu chúng tôi cố gắng xây dựng, trình đóng gói sẽ cài đặt phiên bản 1.4.9 của nokogiri (giả sử chúng tôi không có Gemfile.lock).

Nó có nghĩa là gì ?

Như bạn thấy nếu bạn không có bất kỳ Gemfile.lockvà chạy:

bundle install

sau đó các viên đá quý hiện đang sử dụng có thể khác nhau bất cứ lúc nào . Ứng dụng của bạn sử dụng phiên bản 1.4.4 và nó hoạt động 8 tháng trước mà không cần bất kỳ vấn đề, nhưng nếu bạn cố gắng để xây dựng nó giờ đây bạn sẽ có được phiên bản 1.4.9 . Có thể nó đã bị hỏng với phiên bản mới nhất nokogiri, tính năng tuyệt vời mà bạn đã sử dụng với 1.4.4 không khả dụng hơn, v.v.

Để ngăn chặn loại vấn đề Gemfile.locknày được sử dụng. Trong Gemfile.lockchỉ phiên bản chính xác được viết và do đó chỉ số này sẽ được cài đặt. Điều đó có nghĩa là nếu bạn phân phối ứng dụng của mình với một Gemfile.lock, mọi máy sẽ có cùng các loại đá quý được cài đặt và quan trọng nhất là tất cả chúng đều có cùng một phiên bản . Điều này sẽ cung cấp cho bạn một ngăn xếp triển khai ổn định và phổ biến.

Gemfile.lock được tạo như thế nào?

Nó được tạo tự động với cái đầu tiên:

bundle install

chỉ huy. Sau đó mỗi khi bạn chạy bundle install, gói đầu tiên sẽ tìm kiếm Gemfile.lockvà cài đặt các viên đá quý được chỉ định ở đó. Đó là thói quen phân phối tệp này trong số các dự án của bạn để cung cấp sự ổn định và ổn định.

Làm cách nào để cập nhật Gemfile.lock?

Nếu bạn hài lòng với phiên bản mới nhất của ứng dụng, bạn có thể cập nhật Gemfile.lock. Chỉ cần phản ánh những thay đổi của bạn để Gemfile. Điều đó có nghĩa là thay đổi các phụ thuộc thành các phiên bản chính xác mới trong Gemfile. Sau lần chạy đó:

bundle install

Điều này sẽ cập nhật cho bạn Gemfile.lockvới phiên bản ứng dụng mới nhất của bạn.


19
Một mô tả rất hay, rõ ràng (tôi đã bình chọn); nhưng một nitpick, tuy nhiên: nokogiri ~> 1.4.4sẽ không cho phép 1.5.3cài đặt; tối đa được phép sẽ là 1.4.xnơi x>=4(đối với nokogiri đó sẽ là 1.4.7). Các ~>phương tiện điều hành chỉ là chữ số cuối cùng trong đá quý đã qua sử dụng có thể được "lớn hơn" phiên bản nhất định. Ví dụ, foo ~> a.b.c.dcó nghĩa là bất kỳ phiên bản nào foocũng được miễn là nó vẫn còn abc {Something} trong đó {Something} >=d. Xem thêm câu hỏi liên quan
michael

1
Điều khiến tôi bối rối là bạn đã chỉ định (các) phiên bản cụ thể bằng cách sử dụng gem "nokogiri", "~> 1.4.4"trong gemfile. Tại sao trình đóng gói không thể sử dụng phiên bản đó? Có phải vì nó được thiết kế để cố ý cài đặt các phiên bản mới nhất của đá quý theo mặc định?
Jonny

@Jonny, xem bình luận của michael_n. ~> 1.4.4 không chỉ định phiên bản chính xác.
Matthew Flaschen

2
@Jonny, ~> 1.4.4tương đương với >= 1.4.4 and < 1.5. Xem bundler.io/v1.5/gemfile.html . Đối với một phiên bản chính xác, chỉ cần sử dụng gem 'foo', '1.4.4'.
Matthew Flaschen

1
Câu trả lời tuyệt vời nhưng vui lòng làm rõ " cập nhật Gemfile.lock? ": Phần này có nói rằng bundle installsẽ kiểm tra Gemfilengay cả khi có Gemfile.lockvà thực thi các hạn chế mới Gemfile.lockkhông?
JMess

4

Gemfile.lock

Khi bạn chạy cài đặt gói, Bundler sẽ duy trì tên đầy đủ và phiên bản của tất cả các loại đá quý mà bạn đã sử dụng (bao gồm cả phụ thuộc của các loại đá quý được chỉ định trong Gemfile (5)) vào một tệp có tên Gemfile.lock.

Bundler sử dụng tệp này trong tất cả các lệnh gọi tiếp theo để cài đặt gói, điều này đảm bảo rằng bạn luôn sử dụng cùng một mã chính xác, ngay cả khi ứng dụng của bạn di chuyển trên các máy.

Do cách thức giải quyết phụ thuộc hoạt động, ngay cả một thay đổi dường như nhỏ (ví dụ, bản cập nhật phát hành điểm phụ thuộc của đá quý trong Gemfile của bạn (5)) có thể dẫn đến các loại đá quý khác nhau hoàn toàn cần thiết để đáp ứng tất cả các phụ thuộc.

Do đó, bạn NÊN kiểm tra Gemfile.lock của mình vào kiểm soát phiên bản. Nếu bạn không làm như vậy, mọi máy kiểm tra kho lưu trữ của bạn (bao gồm cả máy chủ sản xuất của bạn) sẽ giải quyết lại tất cả các phụ thuộc, điều này sẽ dẫn đến các phiên bản khác nhau của mã bên thứ ba được sử dụng nếu bất kỳ đá quý nào trong Gemfile (5) hoặc bất kỳ phụ thuộc của họ đã được cập nhật.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.