Вищезгадана стаття є однією з найкращих, яку я прочитав у минулому році. Я
не погоджуюсь з усіма правилами поданими в ній, проте описані ідеї
є надзвичайно цікавими (саме після прочитання її я дізнався, що є обмеження на кількість
оплесків, які ви можете дати). Я спробував застосувати їх у моєму проекті
що був збудований за класичною архітектурою Rails - перебудувати проект було нелегко, проте
результат був безумовно того вартий. Нижче я опишу важливі частини створення локальних gem та engine
в проекті, але для TLDR читачів ось є
Github Repo, в файлі seed.rb знаходяться логін і пароль.
Огляд Gem
Локальний gem дозволяє отримати дані про події з Google Calendar
розділення залежностей
Код в локальному gem має внутрішні залежності, проте повністю незалежний
від проекту в якому використовується. Раніше всі залежності знаходились
в Gemfile батьківського проекту проте були переміщені в файл *.gemspec
всередині gem.
і завантажуються в initializer
розділення тестів
Всі залежні юніт тести були переміщені з батьківського проекту в папку з
локальним gem, їх можна запускати незалежно та ізольовано від
батьківського проекту - перейдіть до папки з gem та запустіть bundle
exec rspec spec/. Необхідні налаштування показано нижче:
Огляд Engine
Engine надає можливість аутентифікації за допомогою authlogic
розділення залежностей
Процес такий же як і для gems, всі залежності перенесено в файл *.gemspec
їх завантаження відбувається в initializer
engine використовує локальний gem google_calendar, його потрібно
завантажити в Gemfile
розділення тестів
Всі юніт тести для engine було переміщено в папку з engine, їх можна
запустити незалежно від основного проекту - перейдіть в папку з тестами
для engine domains/customers/spec/dummy/ і запустіть bundle exec rspec spec/
Налаштування test sute знаходяться в rails_helper.rb
розділення migrations
Я вважаю міграції не повинні копіюватись до батьківського проекту,
необхідні налаштування знаходяться в initializer
розділення локалізацій
Файли з локалізацією можна помістити в папку з engine, налаштування
знаходяться в файлі initializer
Використання аутентифікації в батьківському проекті
Аутентифікація була винесена в concern отож потрібно використати цей concern у controller
Тестування Engine/Gem в батьківському проекті
Я вважаю, що тести, розташовані в engine/gem, повинні бути юніт тестами - вони
повинні швидко запускатись і використовувати stub замість будь-яких зовнішніх залежностей.
Коли потрібно протестувати інтеграцію з іншими engine/gem - використати системні тести.
Приклад:
Висновки
Винести gem було досить легко, винести engine було трохи складніше.
Переваги модульного моноліту над класичним:
Розділення коду - значно вдосконалений дизайн
Розділення залежностей
Розділення тестів - кожен engine/gem має власні тести, які швидко працюють
і можуть запускатись незалежно