แผนภูมิการมีส่วนร่วม GitHub ของคุณเป็นสีเทาทึบ? คุณอาจต้องการ open source project ที่จะทำงาน แต่คุณไม่ต้องเริ่มจากศูนย์ วิธีที่ง่ายที่สุดในการสร้าง side project ที่มีประโยชน์คือการดึงมันออกมาจากแอปที่คุณกำลังสร้างอยู่ นั่นคือวิธีที่ Rails เกิด!
แตคุณรู้ยังไงว่าจะ extract อะไร? และคุณจะเปลี่ยนมันเป็น gem อย่างไร โดยไม่ทำลาย workflow ของคุณ?
หาโค้ดที่คุณต้องการ extract
ที่ไหนซักที่ลึกภายในแอปของคุณ มีโค้ดบางอย่างที่ไม่ควรอยู่ที่นั่น โค้ดที่ไม่ ต้องการ แอปของคุณเพื่อทำงาน มันอยู่ที่ไหน?
บางครั้ง คุณจะต้องเดา แต่ผมมักพบ extractable code ในที่เดียวกันหลายที่:
-
Validations
คุณเคยเขียน custom validations สำหรับ attributes ของคุณไหม? พวกมันทำ gems ที่ยอดเยี่ยมได้
-
การเปลี่ยนแปลงที่คุณทำไปที่ Rails
บางครั้ง คุณจะต้อง mess กับ Rails เพื่อให้ commit hooks ทำงานใน tests หรือ blank attributes กลายเป็น NULL ใน database ทุกครั้งที่ผมย้าย logic ประเภทนี้เข้า gem มันกลายเป็นมั่นคงและเข้าใจง่ายขึ้น
-
Non-activerecord models
คุณทำ email address หรือ phone number parsing มากจนคุณย้ายมันไปคลาสของตัวเอง? คลาสเหล่านี้มักมีประโยชน์ในแอปอื่น และค่อนข้างง่ายที่จะเปลี่ยนเป็น gems
-
Mock objects และ custom assertions
คุณสามารถเขียน tests ที่อ่านง่ายขึ้นโดยใช้ custom assertions และเมื่อคุณมี custom assertions ที่ดีเขียนไว้สำหรับ library หรือ pattern พวกมันมีประโยชน์ต่อคนอื่นที่ใช้ library หรือ pattern นั้น
คุณไม่ต้องคิดใหญ่ บาง gems โปรดของผมคือแค่ไฟล์เดียว!
และหากคุณยังตัดสินใจไม่ได้ว่าจะ extract อะไร ให้瀏覽 category list บน RubyToolbox เพื่อแรงบันดาลใจ
วางโค้ดของคุณใน directory ที่เหมือน gem
เมื่อคุณรู้ว่าโค้ดไหนจะกลายเป็น gem ให้ย้ายโค้ดให้เข้ากับ gem-like structure ภายในแอปของคุณ
ใน Rails apps ผมใช้ lib/ เป็น gem staging area lib/ คือที่ที่ผมวางโค้ดที่มี potential ที่จะกลายเป็น gem ของตัวเอง ดังนั้น หากคุณสร้าง gem ชื่อ "json_api_client" lib/ directory ของ Rails app ของคุณอาจมีลักษณะดังนี้:
... my_rails_app/lib/json_api_client.rb my_rails_app/lib/json_api_client/associations.rb my_rails_app/lib/json_api_client/connection.rb ... Gems ส่วนใหญ่จะมีไฟล์ภายใต้ lib/ ชื่อตาม gem (lib/json_api_client.rb) และชุดไฟล์ใน directory ที่ชื่อตาม gem (ทุกอย่างภายใต้ lib/json_api_client/) ดังนั้น ให้ใช้โครงสร้างเดียวกันและ match มันภายใน Rails app ของคุณ นี่จะทำให้ย้ายโค้ดเข้า gem นั้นง่ายขึ้นภายหลัง
หากคุณสับสนเกี่ยวกับ gem layout 长什么样子 去看看 GitHub 上 你 最喜欢 的 gems 的 source code 你 会 很快 掌握 模式
Tests แล้วล่ะ?
ผมเคย follow lib/'s structure ภายใน test/unit/:
... my_rails_app/test/unit/json_api_client_test.rb my_rails_app/test/unit/json_api_client/associations_test.rb my_rails_app/test/unit/json_api_client/connection_test.rb ... มันทำงานได้ OK แม้ว่าการวาง models และ libraries ในโฟลเดอร์เดียวกันจะมี点 混乱
ตอนนี้ Rails ใช้ test/models/ แทน test/unit/ และเก็บ lib/ tests ภายใน test/models/ ไม่ค่อยมีความหมาย ผมยังไม่ตัดสินใจ convention สำหรับนี้ คุณมีคำแนะนำไหม?
ทำลาย Dependencies
เมื่อโค้ดของคุณอยู่ใน gem มันจะไม่สามารถ depend บนแอปของคุณได้ นี่หมายความว่าคุณจะต้องผ่านโค้ดที่คุณวางใน lib/ และมองหาที่ที่มัน depend บน classes, objects, หรือพฤติกรรมที่เฉพาะเจาะจงกับแอปของคุณ
หากคุณพบ dependencies ใดๆ คุณจะต้องทำลายพวกมัน มีบทความยอดเยี่ยดมากเกี่ยวกับวิธีการ break (หรือ inject) dependencies ดังนั้นผมไม่จะลองอธิบายตอนนี้
สร้าง Gem
ผมใช้ bundle gem เพื่อสร้าง gems ของผม โดยเฉพาะ สร้าง gem ชื่อ bulk_cache_fetcher:
bundle gem bulk_cache_fetcher -t minitest Flag -t เพิ่ม test helper files และ test tasks เข้า Rakefile ของ gem
คุณจะต้องทำ housekeeping ต่อไป เช่น fill out .gemspec, เขียน README, เลือก LICENSE ทุกอย่างนั้น
และจากนั้น เนื่องจากคุณมีโค้ดของ gem อยู่ใน lib/ folder ของ Rails app แล้ว คุณสามารถย้ายโค้ดนั้นและ tests เข้า lib/ และ test/ folders ใน gem ใหม่ของคุณ
บ่อยครั้ง จะมีสิ่งที่คุณพลาดหรือลืม หรือโค้ดที่ assume สิ่งต่างๆ เกี่ยวกับแอปของคุณที่ไม่จริงภายใน gem ดังนั้น ก่อนที่คุณจะขยับต่อ ให้รัน tests ที่คุณย้ายเข้า gem และ ensure ว่าทั้งหมดผ่าน
ใช้ gem ใหม่ของคุณในแอป
ตอนนี้คุณมี gem คุณอยากใช้มันใช่ไหม? แตการทดสอบการเปลี่ยนแปลงใน gem ภายใน Rails app ของคุณอาจรบกวนได้เร็วมาก คุณต้อง:
- ทำการเปลี่ยนแปลงใน gem ของคุณ
- Build the gem
- Remove all traces of the gem จากระบบของคุณ หรือ update version
- Install the gem
- Restart server ของคุณ
นี่ค่อนข้าง awful โชคดีที่ bundler ให้ easy way สมมติว่าคุณสร้าง gem ใน ~/Source/bulk_cache_fetcher ขณะที่คุณทดสอบการเปลี่ยนแปลง gem คุณสามารถเขียนนี้ภายใน Gemfile ของ Rails app:
gem "bulk_cache_fetcher", path: "~/Source/bulk_cache_fetcher" ต่อไป รัน bundle install และคุณจะสามารถทำการเปลี่ยนแปลงใน gem ของคุณได้ انگั้นโค้ดยังคงอยู่ใน lib/ folder ของแอป
สิ่งสุดท้าย: ensure ว่าคุณลบ path: ออกก่อนที่คุณจะ check in โค้ด! path นั้นอาจไม่ชี้ไปที่ที่ถูกต้องบนระบบอื่น ดังนั้นโอกาสมันจะไม่ทำงานที่ไหนนอกจากเครื่องของคุณ
Build, ship, และ enjoy!
เมื่อ gem ของคุณพร้อม คุณสามารถส่งมันออกสู่โลก
ดังนั้น สมัครบัญชีบน RubyGems หากยังไม่มี check in การเปลี่ยนแปลงของคุณ และรัน rake release ขอแสดงความยินดี คุณตอนนี้เป็น gem author แล้ว! และเมื่อคุณ push gem นั้นไป github คุณจะได้สี่เหลี่ยมสีเขียวสวยงามสำหรับวันนั้น
คุณมีส่วนใดของแอปของตัวเองที่ดู extractable ไหม? อะไรที่คุณคิดว่าอาจทำ gem ที่ดี? ผมอยากรู้ - ทิ้ง comment ด้านล่าง
และหากคุณอยากเรียนรู้ เยอะมาก เกี่ยวกับการสร้าง จัดการ และดูแล Ruby gems ผมแนะนำ Brandon Hilkert's Build a Ruby Gem อย่างยิ่ง กระบวนการที่หนังสือของเขาติดตามใกล้เคียงกับนี้ และครอบคลุมมากกว่านี้มาก