How-to: Migrate app to Rhino
Source:vignettes/how-to/migrate-app-to-rhino.Rmd
migrate-app-to-rhino.Rmd
This guide aims to make your application up and running using Rhino as quickly as possible. Lets assume an application has a following structure:
.
├── utils
│ ├── foo.R
│ └── bar.R
├── www
│ ├── main.css
│ └── main.js
├── server.R
└── ui.R
The migration process should not be affected by the combination of server.R, ui.R, global.R, and app.R files in your application, or lack of thereof.
Prepare Your Application for rhino::init()
The first step is moving all application source files to a new app
directory:
.
└── app
├── utils
│ ├── bar.R
│ └── foo.R
├── www
│ ├── main.css
│ └── main.js
├── server.R
└── ui.R
Once source files are moved, if you have a list of library()
calls put it in dependencies.R
in the root directory. If you do not have such list, then Rhino will try to create one for you in initialization step.
.
├── app
│ ├── utils
│ │ ├── bar.R
│ │ └── foo.R
│ ├── www
│ │ ├── main.css
│ │ └── main.js
│ ├── server.R
│ └── ui.R
└── dependencies.R
After doing so, you should be able to run your application using shiny::shinyAppDir("app")
.
What if: My App Uses renv
If you have used renv in your application, then chances are your active renv session does not have Rhino installed. To address this either deactivate renv or run renv::install("rhino")
.
Apart from additional files related to renv, the target file structure is no different than the one presented above.
Initialize Your Rhino Application
Having your application prepared, you can now runrhino::init()
.
.
├── .github
│ └── workflows
│ └── rhino-test.yml
├── app
│ ├── js
│ │ └── index.js
│ ├── logic
│ │ └── __init__.R
│ ├── static
│ │ └── favicon.ico
│ ├── styles
│ │ └── main.scss
│ ├── utils
│ │ ├── bar.R
│ │ └── foo.R
│ ├── view
│ │ └── __init__.R
│ ├── www
│ │ ├── main.css
│ │ └── main.js
│ ├── main.R
│ ├── server.R
│ └── ui.R
├── renv
│ └── ...
├── tests
│ ├── cypress
│ │ ├── e2e
│ │ └── .gitignore
│ ├── testthat
│ │ └── test-main.R
│ └── cypress.json
├── .Rprofile
├── .lintr
├── .renvignore
├── app.R
├── dependencies.R
├── old.Rprofile
├── renv.lock
├── rhino.yml
└── app.Rproj
If you did not use renv before, then Rhino initialized it for you. However, if you did use renv, then Rhino added necessary dependencies to renv.lock
file.
Configure Your Rhino Application
The last step to get started with Rhino is configuring it. A minimal setup that allows running the application is setting legacy_entrypoint
in rhino.yml
. To be able to run application immediately set legacy_entrypoint: app_dir
, as this approach requires no further adjustments to application’s structure.
As you adjust adjust your application to fit best practices suggested by Rhino, you can modify legacy_entrypoint
. Ultimately, when application is fully migrated to Rhino, legacy_entrypoint
setting can be removed from rhino.yml
. Refer to Next Steps section to see how to continue improving your application!
Next Steps
Migrating JavaScript Code
TODO: something along the lines of build_js()
details
Additional notes
The process described in rhino::init()
documentation, albeit not in great detail. The first step is to put all app files in the app
directory, so it can be run with shinyAppDir("app")
. Practical experience of migrating apps shows that it’s a useful step which quickly lets you verify whether the app still works.
The process can be a bit unintuitive however. For example, if you already have an app.R
file and ui/server/global in R
subdirectory, you should still move the whole structure under app
. In this case you’ll end up with app.R
, app/app.R
and ui/server/global in app/R/
. Having two app.R
files might feel awkward.
In general you use rhino::init()
for migration. This cannot be done via RStudio GUI.
If you already have .Rprofile
with renv when migrating, you’ll load it and won’t have Rhino inside. You need to run rhino::init()
from a different directory (or perhaps run renv::deactivate()).
Rhino will renv::load() your renv.lock. In particular it will set your options("repos"
) based on renv.lock
.
What to do when I get “unsatisfied dependencies” during migration?