อะไรคือความแตกต่างระหว่าง Gemfile และ Gemfile.lock ใน Ruby on Rails


คำตอบ:


159

Gemfileเป็นที่ที่คุณระบุอัญมณีที่คุณต้องการใช้งานและช่วยให้คุณสามารถระบุรุ่น

Gemfile.lockไฟล์ที่บันทึก Bundler รุ่นที่แน่นอนที่มีการติดตั้ง วิธีนี้เมื่อโหลดไลบรารี / โปรเจ็กต์เดียวกันบนเครื่องอื่นการรันbundle installจะดูGemfile.lockและติดตั้งเวอร์ชันเดียวกันทั้งหมดแทนที่จะใช้Gemfileและติดตั้งเวอร์ชันล่าสุดเท่านั้น (การเรียกใช้เวอร์ชันต่างๆบนเครื่องที่แตกต่างกันอาจทำให้การทดสอบเสียหาย ฯลฯ ) คุณไม่ควรแก้ไขไฟล์ล็อกโดยตรง

ตรวจสอบวัตถุประสงค์และเหตุผลของ Bundlerโดยเฉพาะในส่วนการตรวจสอบโค้ดของคุณในการควบคุมเวอร์ชัน


2
นั่นเป็นวิธีที่มันควรจะทำงาน - แต่เห็นได้ชัดGemfile.lockรวมถึง 'เปิด' รุ่นในบางกรณี (เช่นrails (4.0.0)ต้องbundler (>= 1.3.0, < 2.0)) ซึ่งทำให้เกิดปัญหา มีความคิดอย่างไรที่จะหลีกเลี่ยงการพึ่งพา 'เปิด' เหล่านั้น?
Guillermo Grau

158

โดยปกติเราจะเขียนการอ้างอิงใน Gemfile เป็น:

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

โดยพื้นฐานแล้วคุณพูดว่า: " ฉันต้องการ nokogiri ตราบใดที่มันมากกว่าเวอร์ชัน 1.4.4 " ฯลฯ สมมติว่าฉันได้ตั้งค่าเมื่อGemfile 8 เดือนที่แล้วและฉันตั้งค่าแอปของฉันได้สำเร็จตามข้อกำหนดนี้ 8 เดือนที่ผ่านมารุ่น nokogiri เป็น1.4.4 แอปรางของฉันทำงานได้อย่างสมบูรณ์โดยไม่มีปัญหากับเวอร์ชันนี้

Gemfileตอนนี้คิดว่าฉันพยายามที่จะสร้างด้วยเหมือนกัน แต่ถ้าเราดูรุ่น nokogiriเราจะเห็นว่าเวอร์ชันเสถียรในปัจจุบันเปลี่ยนเป็น1.4.9แล้ว นั่นหมายความว่าหากเราพยายามสร้างบันเดิลเลอร์จะติดตั้ง nokogiri เวอร์ชัน1.4.9 (สมมติว่าเราไม่มีGemfile.lock)

หมายความว่าอย่างไร?

อย่างที่คุณเห็นว่าคุณไม่มีGemfile.lockและเรียกใช้:

bundle install

แล้วอัญมณีที่ใช้อยู่ในปัจจุบันจะแตกต่างกันในเวลาใดก็ได้ แอปของคุณใช้เวอร์ชั่น1.4.4และการทำงาน8 เดือนที่ผ่านมาไม่มีปัญหาใด ๆ แต่ถ้าคุณพยายามที่จะสร้างมันขึ้นมาตอนนี้คุณจะได้รับรุ่น1.4.9 อาจจะเสียด้วยเวอร์ชันล่าสุดnokogiriฟีเจอร์ที่ยอดเยี่ยมที่คุณใช้กับ1.4.4ไม่มีให้ใช้งานอีกแล้ว ฯลฯ ..

เพื่อป้องกันปัญหาประเภทGemfile.lockนี้ใช้ ในGemfile.lockเฉพาะรุ่นที่แน่นอนจะถูกเขียนและทำให้เหล่านี้เท่านั้นจะถูกติดตั้ง นั่นหมายความว่าถ้าคุณจัดจำหน่ายแอปของคุณด้วยGemfile.lockเครื่องทุกคนจะมีอัญมณีเดียวกันการติดตั้งและที่สำคัญที่สุดที่พวกเขาทั้งหมดได้รับรุ่นเดียวกัน สิ่งนี้จะทำให้คุณมีสแต็กการปรับใช้ที่มีเสถียรภาพ

Gemfile.lock ถูกสร้างขึ้นอย่างไร?

มันถูกสร้างขึ้นโดยอัตโนมัติด้วยสิ่งแรก:

bundle install

คำสั่ง หลังจากนั้นทุกครั้งที่คุณเรียกใช้bundle installบันเดิลจะค้นหาGemfile.lockและติดตั้งอัญมณีที่ระบุไว้ในนั้นก่อน เป็นนิสัยที่จะแจกจ่ายไฟล์นี้ในโครงการของคุณเพื่อให้มีความมั่นคงและสม่ำเสมอ

จะอัพเดต Gemfile.lock ได้อย่างไร?

หากคุณพอใจกับแอปเวอร์ชันล่าสุดเกินกว่าที่จะอัปเดตGemfile.lockได้ Gemfileเพียงแค่สะท้อนให้เห็นถึงการเปลี่ยนแปลงของคุณ นั่นหมายถึงเปลี่ยนการอ้างอิงเป็นเวอร์ชันที่แน่นอนใหม่ในGemfile. หลังจากนั้นให้รัน:

bundle install

การดำเนินการนี้จะอัปเดตคุณGemfile.lockด้วยแอปเวอร์ชันใหม่ล่าสุด


19
คำอธิบายที่ดีและชัดเจนมาก (ฉันโหวต); แต่หนึ่ง nitpick อย่างไรก็ตามnokogiri ~> 1.4.4ไม่อนุญาตให้1.5.3ติดตั้ง อนุญาตสูงสุดจะอยู่1.4.xที่x>=4(สำหรับ nokogiri ที่จะเป็น1.4.7) ตัว~>ดำเนินการหมายถึงตัวเลขสุดท้ายในอัญมณีที่ใช้สามารถ "มากกว่า" เวอร์ชันที่กำหนดได้ เช่นfoo ~> a.b.c.dหมายความว่าเวอร์ชันใด ๆfooก็ใช้ได้ตราบเท่าที่ยังคงเป็น abc {something} ที่ {something} >=d ดูคำถามที่เกี่ยวข้องด้วย
michael

1
สิ่งที่ทำให้ฉันสับสนคือคุณกำลังระบุเวอร์ชันที่เฉพาะเจาะจงอยู่แล้วโดยใช้gem "nokogiri", "~> 1.4.4"ใน gemfile เหตุใดบันเดิลเลอร์จึงใช้เวอร์ชันนั้นไม่ได้ เป็นเพราะได้รับการออกแบบมาเพื่อจงใจติดตั้งอัญมณีเวอร์ชันล่าสุดตามค่าเริ่มต้นหรือไม่?
จอนนี่

@ จอนนี่ดูความคิดเห็นของ michael_n ~> 1.4.4 ไม่ได้ระบุเวอร์ชันที่แน่นอน
Matthew Flaschen

2
@ จอน~> 1.4.4นี่เทียบเท่ากับ>= 1.4.4 and < 1.5. ดูbundler.io/v1.5/gemfile.html gem 'foo', '1.4.4'สำหรับรุ่นที่แน่นอนเพียงแค่ใช้
Matthew Flaschen

1
คำตอบที่ดี แต่โปรดชี้แจง " อัปเดต Gemfile.lock? ": ส่วนนี้ระบุว่าbundle installจะตรวจสอบGemfileแม้ว่าจะมีGemfile.lockและบังคับใช้ข้อ จำกัด ใหม่Gemfile.lockหรือไม่?
JMess

4

Gemfile.lock

เมื่อคุณเรียกใช้การติดตั้งบันเดิล Bundler จะคงชื่อเต็มและเวอร์ชันของอัญมณีทั้งหมดที่คุณใช้ (รวมถึงการอ้างอิงของอัญมณีที่ระบุใน Gemfile (5)) ไว้ในไฟล์ชื่อ Gemfile.lock

Bundler ใช้ไฟล์นี้ในการเรียกถัดไปทั้งหมดเพื่อติดตั้งบันเดิลซึ่งรับประกันว่าคุณจะใช้รหัสเดียวกันเสมอแม้ว่าแอปพลิเคชันของคุณจะย้ายไปตามเครื่องต่างๆ

เนื่องจากวิธีการแก้ปัญหาการพึ่งพาใช้งานได้แม้จะดูเหมือนการเปลี่ยนแปลงเล็กน้อย (ตัวอย่างเช่นการอัปเดตจุดปล่อยการพึ่งพาอัญมณีใน Gemfile ของคุณ (5)) อาจส่งผลให้อัญมณีที่แตกต่างกันอย่างสิ้นเชิงจึงจำเป็นเพื่อตอบสนองการพึ่งพาทั้งหมด

ดังนั้นคุณควรตรวจสอบ Gemfile.lock ของคุณในการควบคุมเวอร์ชัน หากคุณไม่ทำเช่นนั้นทุกเครื่องที่ตรวจสอบที่เก็บของคุณ (รวมถึงเซิร์ฟเวอร์ที่ใช้งานจริงของคุณ) จะแก้ไขการอ้างอิงทั้งหมดอีกครั้งซึ่งจะส่งผลให้มีการใช้รหัสของบุคคลที่สามเวอร์ชันต่างๆหากมีอัญมณีใด ๆ ใน Gemfile (5) หรือใด ๆ อัปเดตการอ้างอิงของพวกเขาแล้ว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.