CommonJS Libs in Ambly
ClojureScript is being updated to support foreign libs packaged using the CommonJS module system. A good explanation is Maria Neise's blog. From the big picture, this helps with using ClojureScript to work with React Native, which uses CommonJS.
For Ambly, the salient aspect of the ClojureScript compiler strategy is that, when invoking cljs.build.api/build
, the CommonJS foreign libs are converted to “native” Google Closure libs, putting them in :output-dir
where they can subsequently be loaded into the JavaScript environment.
But, since Ambly involves a remote compilation architecture, :output-dir
isn't established until the remote device is discovered and the WebDAV volume is mounted. Additionally, the device may have an onboard :output-dir
that is pre-populated to support app bootstrap. These essentially preclude doing a build step prior to setting up the Ambly REPL.
Instead, Ambly relies on dynamic (remote) compilation whenever a namespace is required
. Additionally, :analyze-path
can be used to cause the REPL to reflect the symbols that are actually loaded on the particular device being connected to. And :watch
can be used to cause files to be complied to the device when saved.
Given the above considerations, an experimental approach is currently being employed to cause Ambly to work with the new CommonJS support: Ambly can invoke the same logic that would be invoked during a build, but inside the REPL setup code after :output-dir
is established. (The :foreign-libs
compiler option is passed to the REPL.)
This involves calling process-js-modules
, followed by updating the :js-dependency-index
and conveying the resulting revision to the compiler options (in particular, the :libs
compiler option entries that are set up to replace the :commonjs
subset of :foreign-libs
by Maria's code) to the ClojureScript REPL and compilation environment via the :merge-opts
feature of -setup
:
(let [...
opts (process-js-modules
(assoc opts :output-dir
webdav-mount-point))
_ (swap! *compiler*
assoc :js-dependency-index
(js-dependency-index opts))
...]
...
{:merge-opts opts})
This is a bit technical but is fortunately all fairly straightforward. It works! Here is a demo.
While this approach is experimental, it provides a path to using CommonJS modules with Ambly and eliminates one more hurdle torwards being able to use Ambly for React Native development!