Коли розділити проект на кілька підпроектів


30

Мені хотілося б знати, чи є сенс розділити проект, над яким я працюю, на два сховища замість одного.

З того, що я можу сказати:

  • Frontend буде записаний у html + js
  • Бекенд у .net
  • Захід не залежить від фронтенду, а фронтенд не залежить від бекенда
  • Фронтенд використовуватиме спокійний api, реалізований у бекенді.
  • Frontend може розміщуватися на будь-якому статичному http-сервері.

На даний момент сховище має таку структуру:

корінь:

  • передній / *
  • бекенд / *

Я думаю, що помилка зберігати обидва проекти в одному сховищі. Оскільки обидва проекту не мають залежностей між собою, вони повинні належати до окремих сховищ та, якщо потрібно, батьківського сховища, що має підмодулі.

Мені сказали, що це безглуздо і що ми не отримаємо жодної користі від цього.

Ось кілька моїх аргументів:

  • У нас є два модулі, які не залежать один від одного.
  • Якщо історія джерел обох проектів у довгостроковій перспективі може ускладнити справи (спробуйте пошукати в історії щось на фронталі, тоді як у вас є половина комісій, які абсолютно не пов’язані з помилкою, яку ви шукаєте)
  • Конфлікт та злиття (цього не повинно статися, але якщо хтось натискає на бекенд, змусить іншого розробника витягнути зміни в заднім часі, щоб підштовхнути зміни фронту.)
  • Один розробник може працювати лише на бекенді, але завжди доведеться виводити передній або інший бік.
  • Зрештою, коли прийде час розгортання. Якимось чином інтерфейс може бути розгорнутий на декілька статичних серверів, маючи один сервер резервного сервера. У кожному випадку, люди будуть змушені або клонувати цілий бекенд з ним, або виготовити спеціальний скрипт, щоб надіслати на всі сервери лише фронтенд, або видалити бекенд. Простіше просто натиснути / витягнути лише передній або резервний, ніж обидва, якщо потрібен лише один.
  • Протилежний аргумент (одна людина може працювати над обома проектами). Створіть третій репо з підмодулем та розвивайте його. Історія зберігається відокремленою в окремих модулях, і ви завжди можете створювати теги, у яких версія синхронізу / фронтену дійсно працює разом разом. Об'єднання обох фронтенд / бекенд в одному репо не означає, що вони працюватимуть разом. Це просто злиття обох історії в одне велике репо.
  • Якщо фронтенд / бекенд є субмодулями, це полегшить ситуацію, якщо ви хочете додати до проекту фрілансера. У деяких випадках ви не хочете надати повний доступ до бази даних коду. Наявність одного великого модуля ускладнить справи, якщо ви хочете обмежити те, що можуть "бачити / редагувати" сторонні люди ".
  • Помилка введення та виправлення помилки, я вставив нову помилку у передній частині. Тоді хтось виправить помилку в бекенді. З одним сховищем відкат перед новою помилкою також відкатує бекенд, що може ускладнити виправлення. Мені довелося б клонувати бекенд в іншій папці, щоб сервер працював під час виправлення помилки у передній частині ... потім намагався перенести речі ... Наявність двох сховищ буде безболісною, оскільки переміщення ШОГИ одного репо виграло Я не міняю іншого. І тестування на різні версії бекенда буде безболісним.

Чи може хтось дати мені більше аргументів, щоб переконати їх або хоча б сказати мені, чому безглуздо (складніше) ділити проект на два підмодулі. Проект новий, а база даних коду - кілька днів, тому це не дуже рано виправити.

Відповіді:


23

У моїй компанії ми використовуємо окремий сховище SVN для кожного компонента системи. Я можу вам сказати, що це стає дуже неприємним. Наш процес збирання має стільки шарів абстракції.

Ми робимо це з Java, тому у нас є важкий процес збірки з компіляцією javac, компіляцією прив'язки JibX, перевіркою XML тощо.

Для вашого веб-сайту це може не спричинити великих труднощів, якщо ви насправді не "побудуєте його" (наприклад, PHP ванілі).

Недоліки розбиття продукту на кілька сховищ

  1. Управління збіркою - я не можу просто перевірити код, запустити автономний сценарій збірки та мати продукт, який можна запускати / встановлювати / розгортати. Мені потрібна зовнішня система збирання, яка виходить на кілька репостів, виконує кілька внутрішніх сценаріїв збірки, потім збирає артефакти.
  2. Відстеження змін - Перегляд того, хто змінив що, коли і чому. Якщо виправлення помилок у фронталі вимагає зміни в резервному режимі, тепер для мене є два розбіжні шляхи, на які слід звернутися пізніше.
  3. Адміністрація - чи дійсно ви хочете подвоїти кількість облікових записів користувачів, політику щодо паролів тощо, якими потрібно керувати?
  4. Об’єднання - нові функції, ймовірно, змінять багато коду. Розбивши проект на кілька сховищ, ви множите кількість необхідних об'єднань.
  5. Створення філій - Те саме, що займається розгалуженням, щоб створити гілку, тепер вам потрібно створити гілку у кожному сховищі.
  6. Позначення тегів - після успішного тестування вашого коду потрібно позначити версію для випуску. Тепер у вас є кілька тегів для створення, по одному у кожному сховищі.
  7. Важко щось знайти - Можливо, фронтенд / бэкенд є простим, але він стає слизьким схилом. Якщо ви розділите на достатню кількість модулів, розробникам, можливо, доведеться дослідити, де знаходиться якийсь фрагмент коду в контролі джерела.

Мій випадок трохи екстремальний, оскільки наш продукт розділений на 14 різних репостів, а потім кожне репо ділиться на 4-8 модулів. Якщо я пам’ятаю, у нас десь близько 80 чи «пакетів», які потрібно перевірити окремо, а потім зібрати.

Ваш випадок із простою програмою «бекенд / фронтенд» може бути менш складним, але я все-таки раджу проти цього.

Надзвичайні приклади можуть бути переконливими аргументами за чи проти майже нічого :)

Критерії, які я використовував би для вирішення

Я б розглядав можливість розщеплення продукту на кілька сховищ вихідного коду після розгляду наступних факторів:

  1. Побудова - Чи поєднуються результати побудови кожного компонента разом, щоб утворити продукт? Як і комбінування файлів .class з набору компонентів у ряд файлів .jar або .war.
  2. Розгортання - Чи закінчуєте ви компоненти, які розгортаються разом як один блок або різні блоки, що переходять на різні сервери? Наприклад, сценарії бази даних переходять на ваш сервер БД, тоді як javascript - на ваш веб-сервер.
  3. Зміни - Вони, як правило, часто або разом змінюються? У вашому випадку вони можуть змінюватися окремо, але все ще часто.
  4. Частота розгалуження / злиття - якщо всі перевіряють на стовбур і гілки рідкісні, ви, можливо, зможете піти з ним. Якщо ви часто розгалужуєтесь і зливаєтеся, це може обернутися кошмаром.
  5. Спритність - якщо вам потрібно розробити, протестувати, випустити та розгорнути зміну за мить (можливо, SaaS), чи можете це зробити, не витрачаючи дорогоцінний час на жонглювання гілками та репост?

Ваші аргументи

Я також не згоден з більшістю ваших аргументів щодо цього розколу. Я не заперечу їм усіх, тому що ця довга відповідь буде ще довшою, але деякі з них виділяються:

У нас є два модулі, які не залежать один від одного.

Нечуття. Якщо ви заберете свій бекенд геть, чи працюватиме ваш фронтенд? Це те, що я думав.

Якщо історія джерел обох проектів у довгостроковій перспективі може ускладнити справи (спробуйте пошукати в історії щось на фронталі, тоді як у вас є половина комісій, які абсолютно не пов’язані з помилкою, яку ви шукаєте)

Якщо ваш корінь проекту розбитий на frontend / і backkend /, ви можете переглянути історію цих ієрархій самостійно.

Конфлікти та злиття (цього не повинно статися, але якщо хтось натискає на бекенд, змусить іншого розробника витягнути зміни в бекенде, щоб підштовхнути зміни фронтену.) Один розробник може працювати лише над бекендом, але завжди повинен буде витягнути бекенд або іншим способом навколо.

Розщеплення проекту на різні репости цього не вирішує. Конфлікт прямої конфіденційності та конфіденційний конфлікт все ще залишає вас з 2 конфліктами, будь то 1 сховище раз 2 конфлікти або 2 сховища раз 1 конфлікт. Хтось ще потребує їх вирішення.

Якщо стурбованість полягає в тому, що 2 repos означає, що frontend dev може об'єднати код frontend, тоді як бекенд Dev об'єднує код бекенда, ви все одно можете це зробити з одним сховищем, використовуючи SVN. SVN може зливатися на будь-якому рівні. Можливо, це обмеження чи меркуріальне обмеження (ви позначили обидва, тому не знаєте, яким SCM ви користуєтесь)?

З іншої сторони

Зважаючи на все це, я бачив випадки, коли розділення проекту працює на кілька модулів або сховищ. Я навіть виступав за це один раз для конкретного проекту, де ми інтегрували Solr у свій продукт. Звичайно, Solr працює на окремих серверах, змінюється лише тоді, коли набір змін пов’язаний із пошуком (наш продукт робить набагато більше, ніж пошук), має окремий процес збирання та немає спільних артефактів коду чи створення артефактів.


Поміркованість у всьому, як казала моя мама ...
Вільям Пейн

Щодо мого письма, я пишу фронтенд без бекенда. Я емулюю бекенд із файлами json, і, мабуть, я міг би навіть повністю імітуватися indexedDB у браузері. Тож так, бекенд - це лише сервер, що обслуговує json. Його можна замінити чим завгодно, доки отримані дані відповідають API. Обидва проекти використовують різну систему побудови. Коротше кажучи, це дуже схоже на наявність веб-сайту та мобільного додатка для Android. Додавання мобільного додатку до сховища веб-сервера.
Loïc Faure-Lacroix

Крім того, якщо це було незрозуміло, бекенд і фронтенд не є інтерфейсом користувача / адміністратора. Але фронтенд - це лише ajax-інтерфейс, а бекенд обслуговує json. Користувачі та ролі обробляються по-різному, а адміністраторський інтерфейс буде знаходитись у передній частині. Ідея полягає в тому, щоб обидві частини були ізольованими і не дозволяли генерованому Javascript html завантажувати створений сервером HTML. Сервер повинен обслуговувати лише json або xml.
Loïc Faure-Lacroix

1
Тоді у вас немає проблем зі збіркою чи розгортанням, так що це може бути нормально. Але знову ж таки, якщо ви внесете серйозні зміни, можливо, вам доведеться змінити API, який впливає і на фронтенд, і на бекенд, і, таким чином, ви будете розгалужуватися двічі, зливатися вдвічі, двічі тегнути тощо. не перетворяться на 3 ... 4 ... 12 ... 20, напевно, не погана ідея.
Брендон

Навіть якщо API змінюється, при належному розміщенні версій можна створити версії гілок для кожного інтерфейсу, який підтримує версію API. Запуск повинен мати деяку "зворотну" сумісність і підтримувати старий API максимально довго.
Loïc Faure-Lacroix

3

Деякі ваші аргументи справедливі, а деякі - ні.

У нас є два модулі, які не залежать один від одного.

Це насправді не зовсім вірно. Щоб мати змогу спілкуватися, як передній, так і бек-енд потрібно мати спільний інтерфейс (опис). Це робить слабкий аргумент на користь наявності обох у сховищі. Але лише слабкий аргумент, оскільки це не має великої різниці.

Якщо історія джерел обох проектів у довгостроковій перспективі може ускладнити справи (спробуйте пошукати в історії щось на фронталі, тоді як у вас є половина комісій, які абсолютно не пов’язані з помилкою, яку ви шукаєте)

Це хибний аргумент. Якщо ви хочете дізнатися, як виправлена ​​певна помилка, ви подивіться у програму виправлення помилок, для якої фіксація містить виправлення. І якщо ви хочете дізнатися, як розвивався той чи інший фрагмент коду, ви подивитеся на історію одного файлу (або, принаймні, жменьки). У будь-якому випадку наявність інших файлів, можливо, з інших модулів, у сховищі не повинна ускладнювати речі.

Конфлікт та злиття (цього не повинно статися, але якщо хтось натискає на бекенд, змусить іншого розробника витягнути зміни в заднім часі, щоб підштовхнути зміни фронту.)

Це хибний аргумент. Мені не відомий жоден (наполовину пристойний) VCS, де вам потрібно синхронізувати весь сховище, перш ніж ви зможете здійснити / натиснути зміни. Максимум, вам потрібно синхронізувати папки, що містять змінені файли (а часто лише самі файли).

Один розробник може працювати лише на бекенді, але завжди доведеться витягувати його або навпаки.

Це той самий хибний аргумент, як і попередній.

Зрештою, коли прийде час розгортання. Якимось чином інтерфейс може бути розгорнутий на декілька статичних серверів, маючи один сервер резервного сервера. У кожному випадку, люди будуть змушені або клонувати цілий бекенд з ним, або виготовити спеціальний скрипт, щоб надіслати на всі сервери лише фронтенд, або видалити бекенд. Простіше просто натиснути / витягнути лише передній або резервний, ніж обидва, якщо потрібен лише один.

Залежно від того, як люди передбачають, що буде розгортання, це може бути вагомим аргументом. Якщо розгортання буде здійснено шляхом розпакування zip-файлу / tarbal на сервері, то не має значення, як організовані ваші сховища. Якщо розгортання буде здійснено шляхом перевірки (частини) сховища на сервері, тоді може бути хорошою ідеєю використовувати окремі сховища для модулів, які розгортаються окремо.

Протилежний аргумент (одна людина може працювати над обома проектами). Створіть третій репо з підмодулем та розвивайте його. Історія зберігається відокремленою в окремих модулях, і ви завжди можете створювати теги, у яких версія синхронізу / фронтену дійсно працює разом разом. Об'єднання обох фронтенд / бекенд в одному репо не означає, що вони працюватимуть разом. Це просто злиття обох історії в одне велике репо.

Це справедливий аргумент, але він не настільки сильний.

Якщо фронтенд / бекенд є субмодулями, це полегшить ситуацію, якщо ви хочете додати до проекту фрілансера. У деяких випадках ви не хочете надати повний доступ до бази даних коду. Наявність одного великого модуля ускладнить справи, якщо ви хочете обмежити те, що можуть "бачити / редагувати" сторонні люди ".

Це справедливий аргумент.

Помилка введення та виправлення помилки, я вставив нову помилку у передній частині. Тоді хтось виправить помилку в бекенді. З одним сховищем відкат перед новою помилкою також відкатує бекенд, що може ускладнити виправлення.

Це хибний аргумент, тому що це означатиме, що після двох помилок на одному модулі ви не зможете відновити перший. Будь-який напівпристойний VCS дозволить вам відмовитись майже про будь-яку стару фіксацію (хоча це часто означає, що ви робите нове зобов’язання, яке змінює ці зміни, іноді навіть у верхній частині HEAD).

Мені довелося б клонувати бекенд в іншій папці, щоб сервер працював під час виправлення помилки у передній частині ... потім намагався перенести речі ... Наявність двох сховищ буде безболісною, оскільки переміщення ШОГИ одного репо виграло Я не міняю іншого. І тестування на різні версії бекенда буде безболісним.

Це насправді досить непоганий аргумент. Наявність двох сховищ полегшує тестування сценаріїв, коли розгорнута передня та зворотна частини можуть стати (трохи) не синхронізованими.


Якщо чесно, більшість хибних аргументів можна вирішити за допомогою гілок. Відділення для фронтену та гілка для бекенда. Майстер для синхронізації. Але певним чином поводження з такою галуззю ускладнює справи, ніж два репости.
Loïc Faure-Lacroix

1
@Sybiam: Насправді вони є хибними аргументами, тому що вони не виділяють проблеми, яка може існувати при використанні одного сховища, навіть якщо всі зміни вносяться лише до магістралі / main.
Барт ван Інген Шенау

Я думаю, що Ваша критика справедлива. Я просто не думаю, що це було питанням.
sylvanaar

2

Ця публікація трохи стара, але я хотів би зробити свій внесок. Хоча ваш бек-енд насправді не знає про фронтальний, передній повинен мати запити, відповідні API API. Якщо ви розглядаєте свій бек-енд як API REST, то ви можете визначити файл інтерфейсу, такий як перемикач інтерфейсу YAML. Зараз дійсно є 3 проекти, які ви можете окремо розділити на різні репозиції, як вважаєте за потрібне:

  • Визначення API
  • Бек-енд
  • Передня частина

Визначення API - це залежність від двох інших проектів, скажемо, що ви використовували maven як інструмент введення залежності. Тоді залежить від того, наскільки суворо ви хочете робити версії. Ви можете натягувати версію проекту визначення API кожного разу, коли вносите зміни, щоб забезпечити, що проекти завжди знаходяться у сумісному стані, але вимагає більше накладних витрат, або ви можете використовувати щось на зразок SNAPSHOTS у maven, і виконувати версію лише після того, як ви задоволений тим, що інтерфейс менш накладний, але у вас часто можуть бути несумісність. Але поки ви застосуєте визначення API в передньому і задньому кінці, ви будете добре розбивати проекти на різні сховища.

Ці питання більше стосуються управління залежностями. Навіть якщо проекти не розбиті і знаходяться в одному сховищі, веб-сайт досить легко розмістити в стані, коли передній і задній кінці не синхронізовані. Дійсно, єдиний спосіб зупинити це - насправді визначити контракт між двома, але ви хочете зробити це таким чином, що не з'єднує реалізацію передньої та зворотної частини, як ви замість цього кодуєте інтерфейс впровадження в програмування ОО.

Крім того, щоб превентивно звертатися з критикою, що це створює накладні витрати на підтримку цього файлу інтерфейсу, swagger, наприклад, може навіть створювати заглушки коду для різних мов програмування та рамок, таких як JAX-RS. Таким чином, ви можете створити інтерфейс за обраною технологією, а потім реалізувати цей інтерфейс. Це також додає дуже приємну документацію до вашого бек-енду, що полегшує розробникам, які працюють на передньому рівні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.