Kapan harus memisahkan proyek dalam beberapa sub proyek

30

Saya ingin tahu apakah masuk akal untuk membagi proyek yang saya kerjakan dalam dua repositori, bukan satu.

Dari apa yang bisa saya katakan:

  • Frontend akan ditulis dalam html + js
  • Backend di .net
  • Backend tidak bergantung pada frontend dan frontend tidak tergantung pada backend
  • Frontend akan menggunakan api yang diimplementasikan di backend.
  • Frontend dapat di-host di server http statis.

Sampai sekarang, repositori memiliki struktur ini:

akar:

  • paling depan/*
  • backend / *

Saya pikir itu kesalahan untuk menjaga kedua proyek dalam repositori yang sama. Karena kedua proyek tidak memiliki ketergantungan antara satu sama lain, mereka harus berada dalam repositori individu dan jika diperlukan repositori induk yang memiliki submodula.

Saya telah diberitahu bahwa itu tidak ada gunanya dan bahwa kita tidak akan mendapat manfaat dari melakukan itu.

Inilah beberapa argumen saya:

  • Kami memiliki dua modul yang tidak saling bergantung.
  • Memiliki sumber riwayat kedua proyek dalam jangka panjang dapat mempersulit hal-hal (coba cari dalam sejarah untuk sesuatu di frontend sementara Anda memiliki setengah dari komitmen yang sama sekali tidak terkait dengan bug yang Anda cari)
  • Konflik dan penggabungan (Ini seharusnya tidak terjadi tetapi memiliki seseorang mendorong ke backend akan memaksa pengembang lain untuk menarik perubahan backend untuk mendorong perubahan frontend.)
  • Satu pengembang mungkin hanya bekerja di backend tetapi harus selalu menarik frontend atau sebaliknya.
  • Dalam jangka panjang, kapan saatnya untuk menyebarkan. Dalam beberapa cara, frontend dapat digunakan untuk beberapa server statis sambil memiliki satu server backend. Dalam setiap kasus, orang akan dipaksa untuk mengkloning seluruh backend dengan itu atau membuat skrip khusus untuk mendorong ke semua server hanya frontend atau untuk menghapus backend. Lebih mudah untuk hanya mendorong / menarik hanya frontend atau backend daripada keduanya jika hanya satu yang diperlukan.
  • Argumen tandingan (Satu orang mungkin mengerjakan kedua proyek), Buat repo ketiga dengan submodule dan kembangkan bersama itu. Riwayat disimpan terpisah dalam modul individual dan Anda selalu dapat membuat tag di mana versi backend / frontend benar-benar bekerja bersama dalam sinkronisasi. Memiliki kedua frontend / backend bersama dalam satu repo tidak berarti bahwa mereka akan bekerja bersama. Itu hanya menggabungkan kedua sejarah menjadi satu repo besar.
  • Memiliki frontend / backend sebagai submodul akan membuat segalanya lebih mudah jika Anda ingin menambahkan freelancer ke proyek. Dalam beberapa kasus, Anda tidak benar-benar ingin memberikan akses penuh ke basis kode. Memiliki satu modul besar akan membuat segalanya lebih sulit jika Anda ingin membatasi apa yang dapat dilihat / diedit oleh "orang luar".
  • Pengenalan bug dan memperbaiki bug, saya memasukkan bug baru di frontend. Kemudian seseorang memperbaiki bug di backend. Dengan satu repositori, memutar kembali sebelum bug baru juga akan mengembalikan backend yang bisa membuatnya sulit untuk diperbaiki. Saya harus mengkloning backend di folder yang berbeda agar backend bekerja sambil memperbaiki bug di frontend ... kemudian mencoba untuk memperbaiki keadaan ... Memiliki dua repositori akan tidak menyakitkan karena memindahkan HEAD dari satu repo yang dimenangkan dapat mengubah yang lain. Dan pengujian terhadap versi backend yang berbeda akan tidak menyakitkan.

Dapatkah seseorang memberi saya lebih banyak argumen untuk meyakinkan mereka atau setidaknya memberi tahu saya mengapa tidak ada gunanya (lebih rumit) untuk membagi proyek dalam dua submodul. Proyek ini baru dan basis kode sudah beberapa hari sehingga tidak terlalu cepat untuk diperbaiki.

Loïc Faure-Lacroix
sumber

Jawaban:

23

Di perusahaan saya, kami menggunakan repositori SVN terpisah untuk setiap komponen sistem. Saya dapat memberitahu Anda bahwa itu sangat membuat frustrasi. Proses pembangunan kami memiliki begitu banyak lapisan abstraksi.

Kami melakukan ini dengan Java, jadi kami memiliki proses pembangunan yang berat dengan kompilasi javac, kompilasi binding JibX, validasi XML, dll.

Untuk situs Anda, ini mungkin bukan masalah besar jika Anda tidak benar-benar "membangunnya" (seperti PHP vanilla).

Kerugian untuk membagi produk menjadi beberapa repositori

  1. Manajemen build - Saya tidak bisa hanya checkout kode, menjalankan skrip build mandiri dan memiliki produk runnable / installable / deployable. Saya membutuhkan sistem build eksternal yang keluar ke beberapa repo, menjalankan beberapa skrip build dalam, kemudian merakit artefak.
  2. Ubah pelacakan - Melihat siapa yang mengubah apa, kapan, dan mengapa. Jika perbaikan bug di frontend memerlukan perubahan backend, sekarang ada 2 jalur berbeda untuk saya rujuk kembali nanti.
  3. Administrasi - apakah Anda benar-benar ingin menggandakan jumlah akun pengguna, kebijakan kata sandi, dll. Yang perlu dikelola?
  4. Penggabungan - Fitur baru cenderung mengubah banyak kode. Dengan memecah proyek Anda menjadi beberapa repositori, Anda mengalikan jumlah gabungan yang dibutuhkan.
  5. Pembuatan cabang - Transaksi yang sama dengan bercabang, untuk membuat cabang, Anda sekarang harus membuat cabang di setiap repositori.
  6. Pemberian tag - setelah tes kode Anda berhasil, Anda ingin memberi tag suatu versi untuk rilis. Sekarang Anda memiliki beberapa tag untuk dibuat, satu di setiap repositori.
  7. Sulit untuk menemukan sesuatu - Mungkin frontend / backend mudah, tetapi menjadi lereng yang licin. Jika Anda memecah menjadi modul yang cukup, pengembang mungkin harus menyelidiki di mana beberapa bagian kode hidup dalam kontrol sumber.

Kasing saya agak ekstrem karena produk kami dibagi menjadi 14 repo yang berbeda dan setiap repo kemudian dibagi menjadi 4-8 modul. Jika saya ingat, kami memiliki sekitar 80 atau beberapa "paket" yang semuanya perlu diperiksa secara individu dan kemudian disusun.

Kasus Anda hanya dengan backend / frontend mungkin tidak terlalu rumit, tapi saya tetap menyarankan untuk tidak melakukannya.

Contoh ekstrem bisa menjadi argumen yang meyakinkan untuk atau melawan apa pun :)

Kriteria yang akan saya gunakan untuk memutuskan

Saya akan mempertimbangkan pemisahan produk menjadi beberapa repositori kode sumber setelah mempertimbangkan faktor-faktor berikut:

  1. Build - Apakah hasil membangun setiap komponen bergabung bersama untuk membentuk suatu produk? Seperti menggabungkan file .class dari banyak komponen menjadi serangkaian file .jar atau .war.
  2. Deployment - Apakah Anda berakhir dengan komponen yang disebarkan bersama sebagai satu unit atau unit berbeda yang pergi ke server yang berbeda? Misalnya, skrip basis data pergi ke server DB Anda, sementara javascript masuk ke server web Anda.
  3. Co-change - Apakah mereka cenderung sering berubah atau bersama-sama? Dalam kasus Anda, mereka dapat berubah secara terpisah, tetapi masih sering.
  4. Frekuensi percabangan / penggabungan - jika semua orang memeriksa ke dalam batang dan cabang jarang, Anda mungkin bisa lolos begitu saja. Jika Anda sering bercabang dan bergabung, ini dapat berubah menjadi mimpi buruk.
  5. Kelincahan - jika Anda perlu mengembangkan, menguji, merilis, dan menyebarkan perubahan pada pemberitahuan sesaat (kemungkinan dengan SaaS), dapatkah Anda melakukannya tanpa menghabiskan waktu berharga menyulap cabang dan repo?

Argumen Anda

Saya juga tidak setuju dengan sebagian besar argumen Anda untuk pemisahan ini. Saya tidak akan membantah mereka semua karena jawaban yang panjang ini akan menjadi lebih lama, tetapi beberapa yang menonjol:

Kami memiliki dua modul yang tidak saling bergantung.

Omong kosong. Jika Anda mengambil backend Anda, apakah frontend Anda berfungsi? Itulah yang saya pikir.

Memiliki sumber riwayat kedua proyek dalam jangka panjang dapat mempersulit hal-hal (coba cari dalam sejarah untuk sesuatu di frontend sementara Anda memiliki setengah dari komitmen yang sama sekali tidak terkait dengan bug yang Anda cari)

Jika root proyek Anda dipecah menjadi frontend / dan backend /, maka Anda dapat melihat sejarah hierarki tersebut secara independen.

Konflik dan penggabungan (Ini seharusnya tidak terjadi tetapi memiliki seseorang mendorong ke backend akan memaksa pengembang lain untuk menarik perubahan backend untuk mendorong perubahan frontend.) Satu pengembang mungkin hanya bekerja di backend tetapi harus selalu menarik backend atau sebaliknya. sekitar.

Memisahkan proyek Anda menjadi repo yang berbeda tidak menyelesaikan masalah ini. Konflik frontend dan konflik backend masih menyisakan 2 konflik, apakah itu 1 kali penyimpanan 2 konflik atau 2 repositori kali 1 konflik. Seseorang masih harus menyelesaikannya.

Jika masalahnya adalah 2 repo berarti dev frontend dapat menggabungkan kode frontend sementara dev backend menggabungkan kode backend, Anda masih bisa melakukannya dengan satu repositori menggunakan SVN. SVN dapat bergabung di level apa pun. Mungkin itu adalah batasan git atau mercurial (Anda menandai keduanya, jadi tidak yakin SCM apa yang Anda gunakan)?

Di samping itu

Dengan semua ini dikatakan, saya telah melihat kasus di mana memecah proyek menjadi beberapa modul atau repositori bekerja. Saya bahkan menganjurkannya sekali untuk proyek tertentu di mana kami mengintegrasikan Solr ke dalam produk kami. Solr tentu saja berjalan pada server yang terpisah, hanya perubahan ketika setsetet terkait dengan pencarian (produk kami melakukan lebih dari pencarian), memiliki proses pembuatan yang terpisah dan tidak ada artefak kode atau artefak yang dibuat dibagikan.

Brandon
sumber
Moderasi dalam segala hal, seperti yang ibu saya katakan ...
William Payne
Pada tulisan saya, saya menulis frontend tanpa backend. Saya meniru backend dengan file json, Dan saya mungkin bahkan bisa ditiru sepenuhnya dengan indexedDB di browser. Jadi ya backend hanyalah server yang melayani json. Itu bisa diganti dengan apa saja selama data yang diterima sesuai dengan API. Kedua proyek menggunakan sistem pembangunan yang berbeda. Singkatnya, ini hampir seperti memiliki situs web dan aplikasi android seluler. Menambahkan aplikasi seluler di dalam repositori server web.
Loïc Faure-Lacroix
Juga jika tidak jelas, backend dan frontend bukan antarmuka pengguna / admin. Tapi frontend hanyalah antarmuka ajax dan backend melayani json. Pengguna dan peran ditangani secara berbeda dan antarmuka admin akan berada di frontend. Idenya adalah untuk menjaga kedua bagian terisolasi dan mencegah javascript yang dihasilkan html untuk memuat server yang dihasilkan html. Server seharusnya hanya melayani json atau xml.
Loïc Faure-Lacroix
1
Maka Anda tidak memiliki masalah pembangunan atau penyebaran, sehingga mungkin tidak masalah. Tetapi sekali lagi, jika Anda membuat perubahan besar, Anda mungkin perlu mengubah API, yang mempengaruhi frontend dan backend dan dengan demikian Anda akan bercabang dua kali, menggabungkan dua kali, menandai dua kali, dll. Tetapi selama itu hanya tinggal dua kali dan tidak berubah menjadi 3 ... 4 ... 12 ... 20, mungkin bukan ide yang buruk.
Brandon
Bahkan jika perubahan API, dengan versi yang tepat, dimungkinkan untuk membuat versi cabang untuk setiap frontend yang mendukung versi API. Backend harus memiliki kompatibilitas "mundur" dan menjaga API lama berfungsi selama mungkin.
Loïc Faure-Lacroix
3

Beberapa argumen Anda valid dan sebagian tidak.

Kami memiliki dua modul yang tidak saling bergantung.

Itu sebenarnya tidak sepenuhnya benar. Untuk dapat berkomunikasi, baik front-end dan back-end perlu memiliki antarmuka umum (deskripsi). Itu membuatnya menjadi argumen yang lemah untuk memiliki keduanya dalam repositori bersama. Tetapi hanya argumen yang lemah karena tidak membuat banyak perbedaan.

Memiliki sumber riwayat kedua proyek dalam jangka panjang dapat mempersulit hal-hal (coba cari dalam sejarah untuk sesuatu di frontend sementara Anda memiliki setengah dari komitmen yang sama sekali tidak terkait dengan bug yang Anda cari)

Ini adalah argumen palsu. Jika Anda ingin mencari tahu bagaimana bug tertentu diperbaiki, Anda mencari di pelacak bug yang komitnya berisi perbaikan. Dan jika Anda ingin tahu bagaimana sepotong kode tertentu berkembang, Anda melihat sejarah satu file (atau paling banyak segelintir). Dalam kedua kasus, memiliki file lain, mungkin dari modul lain, dalam repositori tidak boleh menyulitkan hal-hal dengan cara apa pun.

Konflik dan penggabungan (Ini seharusnya tidak terjadi tetapi memiliki seseorang mendorong ke backend akan memaksa pengembang lain untuk menarik perubahan backend untuk mendorong perubahan frontend.)

Ini adalah argumen palsu. Saya tidak mengetahui adanya VCS (setengah layak) di mana Anda perlu menyinkronkan seluruh repositori sebelum Anda dapat melakukan / mendorong perubahan Anda. Paling-paling Anda perlu menyinkronkan folder yang berisi file yang diubah (dan seringkali hanya file itu sendiri).

Satu pengembang mungkin hanya bekerja di backend tetapi harus selalu menarik backend atau sebaliknya.

Ini adalah argumen palsu yang sama dengan yang sebelumnya.

Dalam jangka panjang, kapan saatnya untuk menyebarkan. Dalam beberapa cara, frontend dapat digunakan untuk beberapa server statis sambil memiliki satu server backend. Dalam setiap kasus, orang akan dipaksa untuk mengkloning seluruh backend dengan itu atau membuat skrip khusus untuk mendorong ke semua server hanya frontend atau untuk menghapus backend. Lebih mudah untuk hanya mendorong / menarik hanya frontend atau backend daripada keduanya jika hanya satu yang diperlukan.

Bergantung pada bagaimana orang membayangkan bahwa penyebaran akan dilakukan, ini bisa menjadi argumen yang valid. Jika penyebaran akan dilakukan dengan membongkar file zip / tarbal di server, maka tidak masalah bagaimana repositori Anda diatur. Jika penyebaran akan dilakukan dengan memeriksa (bagian dari) repositori di server, maka itu bisa menjadi ide yang baik untuk menggunakan repositori terpisah untuk modul yang dapat digunakan secara terpisah.

Argumen tandingan (Satu orang mungkin mengerjakan kedua proyek), Buat repo ketiga dengan submodule dan kembangkan bersama itu. Riwayat disimpan terpisah dalam modul individual dan Anda selalu dapat membuat tag di mana versi backend / frontend benar-benar bekerja bersama dalam sinkronisasi. Memiliki kedua frontend / backend bersama dalam satu repo tidak berarti bahwa mereka akan bekerja bersama. Itu hanya menggabungkan kedua sejarah menjadi satu repo besar.

Ini adalah argumen yang valid, tetapi tidak terlalu kuat.

Memiliki frontend / backend sebagai submodul akan membuat segalanya lebih mudah jika Anda ingin menambahkan freelancer ke proyek. Dalam beberapa kasus, Anda tidak benar-benar ingin memberikan akses penuh ke basis kode. Memiliki satu modul besar akan membuat segalanya lebih sulit jika Anda ingin membatasi apa yang dapat dilihat / diedit oleh "orang luar".

Ini adalah argumen yang valid.

Pengenalan bug dan memperbaiki bug, saya memasukkan bug baru di frontend. Kemudian seseorang memperbaiki bug di backend. Dengan satu repositori, memutar kembali sebelum bug baru juga akan mengembalikan backend yang bisa membuatnya sulit untuk diperbaiki.

Itu adalah argumen palsu, karena itu berarti bahwa setelah dua perbaikan bug ke satu modul, Anda tidak akan dapat mengembalikan yang pertama. VCS setengah layak apa pun akan memungkinkan Anda untuk memutar mundur hampir semua komit lama (meskipun itu sering berarti Anda membuat komit baru yang membalikkan perubahan itu, kadang-kadang bahkan untuk bagian atas HEAD).

Saya harus mengkloning backend di folder yang berbeda agar backend bekerja sambil memperbaiki bug di frontend ... kemudian mencoba untuk memperbaiki keadaan ... Memiliki dua repositori akan tidak menyakitkan karena memindahkan HEAD dari satu repo yang dimenangkan dapat mengubah yang lain. Dan pengujian terhadap versi backend yang berbeda akan tidak menyakitkan.

Ini sebenarnya argumen yang cukup bagus. Memiliki dua repositori memudahkan untuk menguji skenario di mana ujung depan dan belakang yang digunakan mungkin menjadi (sedikit) tidak sinkron.

Bart van Ingen Schenau
sumber
Sejujurnya, sebagian besar argumen palsu dapat diselesaikan dengan cabang. Cabang untuk frontend dan cabang untuk backend. Master untuk sinkronisasi. Tetapi dalam beberapa hal, menangani cabang seperti itu membuat segalanya lebih rumit daripada memiliki dua repo.
Loïc Faure-Lacroix
1
@ Sibiam: Sebenarnya, mereka adalah argumen palsu, karena mereka tidak menyoroti masalah yang mungkin ada dengan menggunakan repositori tunggal, bahkan jika semua perubahan hanya dilakukan pada trunk / main.
Bart van Ingen Schenau
Saya pikir kritik Anda valid. Saya hanya tidak berpikir bahwa itulah inti dari pertanyaan itu.
sylvanaar
2

Posting ini agak lama tetapi saya ingin berkontribusi. Sementara back-end Anda tidak benar-benar tahu tentang front-end, front-end perlu memiliki permintaan yang cocok dengan API back-end. Jika Anda menganggap back-end Anda sebagai REST API, maka Anda bisa mendefinisikan file antarmuka seperti antarmuka YAML yang terlalu tinggi. Sekarang ada benar-benar 3 proyek, yang Anda dapat secara individual membagi menjadi beberapa repo yang Anda inginkan:

  • Definisi API
  • Back-end
  • Paling depan

Definisi API adalah ketergantungan pada dua proyek lainnya, katakanlah Anda menggunakan pakar sebagai alat injeksi ketergantungan. Maka itu tergantung seberapa ketat Anda ingin melakukan versi. Anda dapat meningkatkan versi proyek definisi API setiap kali Anda membuat perubahan untuk memastikan proyek selalu dalam kondisi yang kompatibel tetapi membutuhkan lebih banyak overhead, atau Anda dapat menggunakan sesuatu seperti SNAPSHOTS di pakar, dan hanya melakukan versi sekali Anda senang dengan antarmuka yang lebih sedikit overhead tetapi Anda mungkin sering tidak kompatibel. Tetapi selama Anda menegakkan definisi API di depan dan belakang Anda, Anda akan baik-baik saja membagi proyek ke dalam repositori yang berbeda.

Masalah-masalah ini lebih lanjut tentang mengelola ketergantungan. Bahkan jika proyek tidak terpecah dan berada dalam repositori yang sama, cukup mudah bagi situs web untuk dimasukkan ke dalam keadaan di mana ujung depan dan ujung belakang tidak sinkron. Sungguh satu-satunya cara untuk menghentikan ini adalah dengan benar-benar mendefinisikan kontrak antara keduanya, tetapi Anda ingin melakukannya dengan cara yang tidak memadukan implementasi dari front dan back-end, sama seperti Anda akan kode ke antarmuka sebagai gantinya implementasi dalam pemrograman OO.

Juga untuk lebih dulu menangani kritik bahwa ini menciptakan overhead untuk mempertahankan file antarmuka ini, angkuh misalnya bahkan dapat menghasilkan potongan kode untuk berbagai bahasa dan kerangka kerja pemrograman seperti JAX-RS. Jadi, Anda dapat menghasilkan antarmuka dalam teknologi yang Anda pilih dan kemudian mengimplementasikan antarmuka ini. Ini juga menambahkan dokumentasi yang sangat bagus untuk back-end Anda, sehingga memudahkan pengembang front-end untuk melakukan pekerjaan mereka.

Snickers3192
sumber