Introduction
The Emscripten WebAssembly environment provides a virtual filesystem (VFS) which supports the concept of mounting. With this, an entire file and directory structure can be packaged into a filesystem image to be loaded and mounted at runtime by WebAssembly (Wasm) applications. We can take advantage of this interface to efficiently mount R package libraries, pre-packaged and containing potentially many related R packages, in the VFS accessible to webR.
Building an R package library
To build an R package library image we must first build one or more
Wasm R packages using add_pkg()
. As an example, let’s build
a package with a few hard dependencies. Ensure that you are running R in
an environment with access to Wasm development tools1, then run:
rwasm::add_pkg("dplyr")
After the build process has completed, the new repo
directory contains a CRAN-like package repository with R packages build
for Wasm.
Next, run the following to build an Emscripten VFS image:
rwasm::make_vfs_library()
By default, this function will create a new directory named
vfs
if it does not exist. The files
vfs/library.data
and vfs/library.js.metadata
together form an Emscripten filesystem image containing an R package
library consisting of all the packages previously added to the CRAN-like
repository in repo
using add_pkg()
.
Packaging arbitrary data
It is also possible to package an arbitrary data directory as an
Emscripten filesystem image using the file_packager()
function:
rwasm::file_packager("./some/data/directory", out_name = "output_image.data")
Again, this function writes output filesystem images to the
vfs
directory by default.
Mounting filesystem images
The filesystem image(s) should now be hosted by a web server so that
it is available at some URL. Such a URL can then be passed to
webr::mount()
to be made available on the virtual
filesystem for the Wasm R process.
Local testing
The following R command starts a local web server to serve your
filesystem image for testing2. When serving your files locally, be sure
to include the Access-Control-Allow-Origin: *
HTTP header,
required for downloading files from a cross-origin server by the CORS
mechanism.
httpuv::runStaticServer(
dir = ".",
port = 9090,
browse = FALSE,
headers = list("Access-Control-Allow-Origin" = "*")
)
Once the web server is running start a webR session in your browser,
such as the console at https://webr.r-wasm.org/latest/. Use
webr::mount()
to make the R library image available
somewhere on the VFS3:
webr::mount("/my-library", "http://127.0.0.1:9090/vfs/library.data")
Once mounted, the contents of the filesystem image are available at
/my-library
in the virtual filesystem.
list.files("/my-library")
#> [1] "R6" "cli" "dplyr" "fansi" "generics" "glue"
#> [7] "lifecycle" "magrittr" "pillar" "pkgconfig" "rlang" "tibble"
#> [13] "tidyselect" "utf8" "vctrs" "withr"
This new directory should be added to R’s .libPaths()
,
so that R packages may be loaded from the new library.
Deployment
The filesystem image files should be deployed to the static file
hosting service of your choice, so that they are available for download
anywhere. See the “Deployment to static hosting” section in
vignette("rwasm")
for an example of how to host static
files with GitHub pages, substituting the repo
directory
for the vfs
directory containing Emscripten filesystem
images.