(Acest articol a fost publicat pentru prima dată pe Jakub :: Sobolewskiși a contribuit cu drag la R-Bloggers). (Puteți raporta problema despre conținutul de pe această pagină aici)
Doriți să vă împărtășiți conținutul pe R-Bloggers? Faceți clic aici dacă aveți un blog sau aici dacă nu.
Mai multe aplicații strălucitoare care împărtășesc logica comună solicită o strategie de implementare diferită decât aplicațiile autonome.
În funcție de dimensiunea proiectului, puteți alege
- un multiRepo: fiecare aplicație din propriul său depozit, R pachete (e) pentru logică partajată sau
- Un monorepo: toate aplicațiile și logica partajată într -un singur depozit.
Ambele opțiuni au pro și contra.
Abordarea multiRepo este mai ușoară din perspectiva de implementare strălucitoare (sau rapoarte) (în special pentru serverele POSIT), deoarece fiecare aplicație are propriul repo și este un director implementat. Cu toate acestea, poate fi mai greu de întreținut, deoarece trebuie să sari între depozite pentru a face modificări logicii partajate.
Aici explorez abordarea monorepo, unde logica partajată este încorporată într -un pachet R și fiecare aplicație este un subdirector al pachetului.
Când construiți mai multe aplicații strălucitoare interconectate (sau rapoarte) care au nevoie de funcții partajate, utilități de procesare a datelor sau configurație comună, combinarea lor într -un pachet R creează un mediu în care puteți dezvolta toate aspectele proiectului într -un singur depozit. Funcțiile dvs. partajate trăiesc în pachetul R/ director în timp ce aplicațiile individuale se află în inst/apps/.
Dacă rezolvarea unei probleme de afaceri necesită puține aplicații sau rapoarte diferite, această structură poate fi foarte eficientă. O soluție la problemă trăiește într -un singur depozit.
Această structură vă permite să implementați fiecare aplicație în mod independent, dar să o expediați cu aceeași logică partajată.
Nivelați-vă jocul de testare! Prindeți -vă copia foii de parcurs a testării R.
Pentru a implementa conținut cu rsconnect::deployApp()trebuie să -l îndreptați către un director care conține un appPrimaryDoc în appDir.
Această limitare pare să nu permită o abordare monorepo în care fiecare aplicație este propriul director, iar logica împărtășită trăiește alături de ei în propriul director.
myproject/ ├── R/ # Shared functions ├── dashboard/ ├── form/ └── report/
Implementare cu rsconnect::deployApp("dashboard") nu va funcționa, ca R/ Directorul nu se află în directorul aplicației. Codul nu va fi expediat în pachetul de implementare și aplicația nu va funcționa.
Este nebun că trebuie să luați în considerare platforma de implementare atunci când vă structurați proiectul … dar putem lucra în jurul acestei limitări.
Structura pachetului
mypackage/
├── R/ # Shared functions
├── inst/apps/ # Individual apps
│ ├── dashboard/
│ │ ├── R/
│ │ │ ├── server.R
│ │ │ └── ui.R
│ │ ├── tests/
│ │ │ └── testthat/
│ │ │ ├── setup-shinytest2.R
│ │ │ └── test-app.R
│ │ ├── app.R
│ ├── form/
│ │ └── app.R
│ └── report/
│ ├── index.qmd
│ └── functions.R
└── tests/
└── testthat/
inst/apps/ Directorul devine sursa de implementare. Fiecare subdirector conține o aplicație strălucitoare completă care poate fi de referință funcții din pachetul părinte R/ director
Funcția de implementare
Scriptul de implementare creează un temporar app.R fișier care încarcă pachetul și lansează aplicația specifică:
deploy <- function(file, title, ...) {
writeLines(
c(
'pkgload::load_all()',
'options(shiny.autoload.r = FALSE)',
sprintf('shiny::shinyAppDir("%s")', file)
),
"app.R"
)
on.exit(unlink("app.R"))
rsconnect::deployApp(
appPrimaryDoc = "app.R",
appName = title,
appTitle = title,
...
)
}
Această abordare imită golemStrategia de implementare. Cei generați app.R utilizări pkgload::load_all() Pentru a pune la dispoziție funcțiile pachetului, apoi lansează directorul de aplicații specific cu shinyAppDir().
Din moment ce ne implementăm din rădăcina pachetului, R/ Directorul este inclus în pachetul de implementare și toate funcțiile partajate sunt disponibile pentru aplicație.
Implementare multiplă a aplicațiilor
Implementați fiecare aplicație în mod independent, specificând diferite directoare:
deploy("inst/apps/dashboard", "dashboard")
deploy("inst/apps/form", "form")
Fiecare implementare creează o aplicație separată. Aplicațiile partajează același cod de pachet de bază, dar prezintă interfețe diferite sau servesc scopuri diferite.
De ce să alegeți această structură?
Această structură acceptă o iterație rapidă în cazul în care logica partajată evoluează alături de aplicații individuale / conținut implementat.
Modificări ale funcțiilor din R/ afectează imediat toate aplicațiile care le folosesc. Modificările specifice aplicației rămân izolate în directoarele lor respective. Cred că funcționează cel mai bine pentru proiecte mici și mijlocii, unde aplicațiile sunt strâns legate și logica de partajare.
Abordarea multiRepo ar putea fi mai bună pentru:
- proiecte mai mari,
- unde aplicațiile sunt gestionate de diferite echipe,
- Sau aveți o implementare perfectă în care fiecare aplicație și dependențele sale pot fi ușor implementate independent.
Aceasta a fost experiența mea cu un proiect care necesită mai multe aplicații strălucitoare care partajează logica comună.
Dacă aveți sugestii sau îmbunătățiri, vă rugăm să contactați!
