-
Notifications
You must be signed in to change notification settings - Fork 0
/
preface.qmd
168 lines (90 loc) · 13.7 KB
/
preface.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# Preface {#sec-preface .unnumbered}
```{r}
#| eval: true
#| echo: false
#| include: false
source("_common.R")
"#3a506b"
```
Shiny App-Packages attempts to combine and distill Shiny *and* R package development practices from multiple resources.
## Why this book?
:::: {layout="[75, 25]" layout-valign="center"}
[Did you read [R Packages, 2ed](https://r-pkgs.org/) and find it difficult to apply package development practices to your Shiny application?]{style='font-size: 1.05em; font-weight: bold; font-style: italic; color: #3a506b;'}
![](images/rpkgs_cover.png){class="cover" width="300" fig-align="right"}
::::
[R Packages, 2ed](https://r-pkgs.org/) is _the_ premier resource for learning the best practices when creating functions, writing documentation, managing package namespaces, and many other fundamental aspects of package development. However, [R Packages, 2ed](https://r-pkgs.org/) primarily focuses on creating conventional R packages, so doesn't cover Shiny programming (designing user interfaces, server-side computations, modules, etc.). Moreover, testing and debugging a Shiny application differs from the traditional methods used in R packages.
:::: {layout="[25, 75]" layout-valign="center"}
![](images/mastering_shiny_cover.png){class="cover" width="300" fig-align="left"}
[Did you read [Mastering Shiny](https://mastering-Shiny.org/) and want to learn more about package development?]{style='font-size: 1.10em; font-weight: bold; font-style: italic; color: #3a506b;'}
::::
[Mastering Shiny](https://mastering-shiny.org/) is an excellent introduction to the world of [Shiny](https://shiny.posit.co/) and provides a foundation of best practices for developing applications. R packages *are* introduced near the [end of Mastering Shiny](https://mastering-shiny.org/scaling-packaging.html), and this chapter is a great place to start.[^r-pkgs-testing-diffs] However, to fully understand and appreciate the benefits of developing your Shiny app as an R package, it's helpful to have an example app-package that includes the full suite of the package development tools (loading, documenting, testing, installing, etc.).[^mastering-shiny-app-packages-1]
[^r-pkgs-testing-diffs]: [Testing Shiny apps](https://shiny.posit.co/r/articles/improve/testing-overview/) requires additional packages and tools to ensure an application's reliability and performance.
[^mastering-shiny-app-packages-1]: The ['Converting an existing app' chapter](https://mastering-shiny.org/scaling-packaging.html#converting-an-existing-app) provides an example of converting a Shiny app into an R Package. However, many of the helpful package development tools [aren't available](https://github.com/hadley/monthApp) (i.e., `roxygen2` tags, `NAMESPACE` imports/exports, tests, vignettes, etc.).
### Other Shiny Resources
Throughout the course of writing this book, the Shiny community has grown and other resources have been published for developing and customizing Shiny applications. Two popular resources are [Engineering Production-Grade Shiny Apps](https://engineering-shiny.org/) and [Outstanding User Interfaces with Shiny](https://unleash-shiny.rinterface.com/).
:::: {layout="[75, 25]" layout-valign="top"}
[Engineering Production-Grade Shiny Apps](https://engineering-shiny.org/) introduces the [`golem`](https://thinkr-open.github.io/golem/) package, which is an ‘*opinionated framework for building production-grade Shiny applications*’. `golem` offers a robust and standardized way to build, maintain, and deploy production-grade Shiny apps. Whether due to the learning curve, number of features, dependencies, or a particular set of deployment constraints, `golem` might not be the right fit for your application.[^golem-app-packages-2]
![](images/epgsa_cover.png){width="150" fig-align="left"}
::::
:::: {layout="[25, 75]" layout-valign="top"}
![](images/ouiws_cover.png){width="220" fig-align="right"}
[Outstanding User Interfaces with Shiny](https://unleash-shiny.rinterface.com/) '*addresses a specific gap between the beginner and advanced level*' focusing on customizing your Shiny application with HTML, CSS and JavaScript. It introduces [`charpente`](https://rinterface.github.io/charpente/), which streamlines the creation of Shiny development by quickly creating an R package, importing external web dependencies for JavaScript and CSS, initializing input/output bindings, and providing custom handler boilerplates. `charpente` also offers a high-level interface to `htmltools` (the workhorse that converts R code to web-friendly HTML).
::::
We'll cover both of these texts more in the [frameworks section](frameworks.qmd).
[^golem-app-packages-2]: `golem` apps *are* built as packages. Still, [EPGSA](https://engineering-shiny.org/) assumes the reader is '[comfortable with building an R package.](https://engineering-shiny.org/structuring-project.html#resources)' (*if you're familiar with package development, [EPGSA](https://engineering-shiny.org/) is an excellent resource*).
## How to read this book
Transitioning from programming in R to building Shiny applications and writing R packages presents a steep learning curve. The chapters in this book are aimed flattening the package development portion of that curve. As with any new skill, app-package development involves new mental models, concepts, terminology, habits, and details. If you find yourself getting frustrated, I recommend the 15 minute rule:
> *"By forcing yourself to try for 15 minutes, you gain a deeper understanding of what you're troubleshooting so that, even if you don't fix it in 15, next time you're in a better position to troubleshoot than you were the last time*.
>
> *And by forcing yourself to ask for help after 15, you not only limit the amount of banging-your-head time, but you also get to see how the other person solves the problem while all the details are still fresh in your mind, so that you'll more likely have a deeper understanding of why what you were doing to fix it wasn't working, and why the ultimate solution actually worked."* - [Hacker News, 2013](https://news.ycombinator.com/item?id=6496855)
The chapters in this book (roughly) represent the steps of R package development, but through the lens of an existing Shiny application.[^intro-bwas] Each topic can be applied to creating a new app-package, but--in my experience--many Shiny developers have existing applications they'd like to convert into an R package.
[Introduction](intro.qmd) covers the development of a Shiny app project and it's gradual conversion into an R package:
- @sec-whole-game is a 'whole game' for the development of a toy app-package. This chapter gives a high-level overview of the app-package development workflow.[^r-pkgs-whole-game]
- In @sec-shiny we'll dive into shiny development, focusing on the files and folders found in most Shiny applications.
- R packages are introduced in @sec-pkgs, and it covers the differences between Shiny app projects, R packages, and Shiny app-packages.
- @sec-dev introduces `devtools` and the app-package development workflow.
[App-packages](app_packages.qmd) applies the key components of R package development to a Shiny app:
- @sec-doc covers documenting the application's utility functions, modules, UI, server, and standalone app function using `roxygen2`.
- Managing dependencies (both imports and exports) using the `NAMESPACE` file is introduced in @sec-depends
- @sec-data discusses the storage, format, and documentation of data files your app-package.
- There are multiple ways to launch an application from an app-package. @sec-launch covers options to include in the `app.R` file and your standalone app function.
- @sec-inst covers the many uses of the `inst/` folder in R packages. This chapter also covers how to add external files and resources to your application.
[^r-pkgs-whole-game]: R Packages, 2ed, has a [similar chapter](https://r-pkgs.org/whole-game.html) that covers developing standard R packages.
[^intro-bwas]: The original code and data for the application in this book comes from the [Building Web Applications with Shiny (BWAS)](https://rstudio-education.github.io/shiny-course/) course.
While developing your application, you'll want to ensure it's features are documented and tested. The [Tests](tests.qmd) section covers testing:
- Before running any tests we need to set up the test suite in our app-package. @sec-tests-suite briefly covers setting up the testing infrastructure with `testthat`.
- Knowing what features to implement and what tests to develop reduces the chances of writing code that doesn't address a user needs. @sec-tests-specs discusses how to identify user specifications, features, and functional requirements. It also briefly introduces behavior-driven development.
- @sec-tests-tools covers how to include testing tools (fixtures and helpers) in your test suite to ensure isolated yet controllable test conditions.
- Reactivity makes testing modules tricky. In @sec-tests-mods, I'll cover some strategies and approaches for verifying that your modules are communicating correctly with Shiny's `testServer()` function.
- @sec-tests-system introduces performing system (or end-to-end) tests in you app-package with the [`shinytest2` package](https://rstudio.github.io/shinytest2/).
After you've developed your Shiny App-Package, you'll likely want to deploy it (or put it '*into production*'). A selection of popular methods are covered in [Deploy](deploy.qmd):
- @sec-docker explains how build Docker images and containers using Docker desktop. These topics are also covered in @sec-golem.
- @sec-gha-cicd covers continuous integration (CI) / continuous deployment (CD) for Shiny app-packages using GitHub Actions.
- @sec-pkgdown websites are an excellent way to enhance it's visibility and usability of your app-package (and it's made seamless with `usethis` and GitHub actions (see @sec-pkgdown-workflow)).
Shiny apps often contain non-R code files, such as CSS or JavaScript, for custom visualizations, widgets, enhanced HTML reports, etc. Including these files in your app-package (and then accessed from your R code) is covered in [Code](code.qmd):
- @sec-html (*this chapter is under construction*)
- @sec-css introduces where to store code used for styling your application (*this chapter is under construction*)
- @sec-js (*this chapter is under construction*)
- @sec-style (*this chapter is under construction*)
If you're Googling '*what is the best way to build a Shiny application?*' you'll eventually encounter a Shiny [framework.](frameworks.qmd) This section contains the development workflow and methods for three popular Shiny application frameworks (`golem`, `leprechaun`, `charpente` and `rhino`).
- @sec-golem covers developing an application using the `golem` framework (which is introduced in [Engineering Production-Grade Shiny Apps](https://engineering-shiny.org/)).
- For developers looking for a 'lightweight' version of the `golem` package, @sec-leprechaun introduces the `leprechaun` package and development workflow
- @sec-charpente is the Shiny framework introduced in [Outstanding User Interfaces with Shiny](https://unleash-shiny.rinterface.com/workflow-charpente.html#workflow-charpente).
- @sec-rhino covers how to build a `rhino` application (which is not *technically* a package, but is still worth including based on it's popularity and features).
The [special topics](special_topics.qmd) section includes a handful of topics on development, storing and retrieving data, reading error outputs, and keeping track of dependencies.
- @sec-debug covers strategies and tricks for debugging errors and exploring reactivity in your Shiny app.
- @sec-app-data explores the differences between and use of `shiny::reactiveValues()` and `session$userData`.
- @sec-stack-traces (*this chapter is under construction*)
- @sec-entanglement (*this chapter is under construction*)
## Acknowledgments
This book is the result of multiple discussions with 1) Shiny developers who were new to writing R packages, 2) R package authors who were learning Shiny development and testing, and 3) new R users who wanted to build a robust and scalable application. Shiny App-Packages wouldn't have been possible without the contributors below (and I am deeply grateful for all of their help!).
- [Henry Bernreuter](https://github.com/HenryBernreuter) & [Elizabeth Marshallsay](https://www.youtube.com/@lilybuguk) for the initial discussions that created the outline for this book
- [Andrew Bates](https://github.com/asbates) for being an exemplary developer and professional, quietly building outstanding UIs, applications, and packages
- [Eric Simms](https://github.com/esimms999) for asking so many great questions, reviewing chapters, and giving phenomenal feedback
- [Eric Nantz](https://github.com/rpodcast)[^nantz-linkedin] for his [R podcast](https://r-podcast.org/), [Shiny developer series](https://shinydevseries.com/), [workshops](https://posit-conf-2023.github.io/shiny-r-prod/), and everything else he does for the Shiny community
- [Philip Bowsher](https://github.com/philbowsher) for everything he does for the R/Pharma conference and community
- [Ted Laderas](https://github.com/laderast) for his excellent [gRadual intRoduction to Shiny](https://laderast.github.io/gradual_shiny/) course and insightful blog posts
- [Jennifer Bryan](https://github.com/jennybc) and [Hadley Wickham](https://github.com/hadley) for their posit::conf(23) [package development masterclass workshop.](https://github.com/posit-conf-2023/pkg-dev-masterclass)
- [Maya Gans](https://github.com/MayaGans) for having multiple conversations and Shiny modules and package dependencies
- [Leon Samson](https://github.com/LDSamson) for his feedback on the testing chapters
[^nantz-linkedin]: Eric's [LinkedIn](https://www.linkedin.com/in/eric-nantz-6621617)