Developing mobile digital key applications with ClojureScript
vouch.ioSome technical points about Krell. It leverages the ClojureScript `:bundle` target which was released last year https://clojurescript.org/news/2020-04-24-bundle-target. By simply producing output that is JS bundler friendly we can just piggieback on Facebook's Metro just like we piggieback on Webpack etc. when targeting the web.
We simply reuse the debug loader provided by Google Closure and load ClojureScript and Google Closure JavaScript files through the Metro server. But this is the core of ClojureScript's hot-reloading capabilities without caveats. In Google Closure namespaces can be represented as nested JavaScript objects which delivers pervasive late-binding - which simply cannot be done with ES6 modules because imports will be captured (early bound).
The REPL bit (which is an independent piece from the hot-reloader) just runs on top of react-native-tcp-socket.
The only tricky part is that we need to be able to require Node libraries and assets into ClojureScript during development. This is done by a compiler pass - first we start at the entry point of the ClojureScript React Native project and follow the dep graph collecting all libraries required from `node_modules`. This is dumped to a file that is required transitively by `index.js`.
Asset handling is done as a simple compiler pass over every AST node searching for JavaScript `require` statements in the ClojureScript.
The end result is that we have an extremely rapid development workflow that simply is not possible with other existing technologies - not React Native, not Flutter, not SwiftUI. All of our apps are built via live-coding from our text editor of choice + REPL (either embedded in IDE or via shell).
Happy to answer any further questions!
> which simply cannot be done with ES6 modules because imports will be captured
I'm probably misunderstanding the problem here, but perhaps it's worth noting that ES6 module exports declared with let/var can be changed from within the module and the changes reflect to importing modules, even to named imports.
Logs 1, 2, 3, etc... At least Webpack also compiles ES modules in a way that keeps this functionality.// a.mjs export let counter = 0 setInterval(() => counter++, 1000) // b.mjs import { counter } from './a.mjs' setInterval(() => console.log(counter), 1000)
It's a very good example of a front-end REPL. I used to think hot reloading was good, but to keep the state between reloads is a whole new level.
Yeah, being able to reliably preserve state between reloads is an incredible productivity boost. It's also fantastic for figuring out what's going on in the app. Any time you're not sure what a particular piece of code does, you can just run it and see the output.
I find the REPL removes a lot of stress and frustration from the development process. I run every function I write to see that it's doing what was intended. Then once I'm happy with it, I move to the next step, and so on. So, the only context that I need to keep in my head tends to be what the last function I wrote did, and what the current function that I'm writing is doing. In vast majority of cases any errors I see are going to be found in the last couple functions that I wrote.
Krell looks pretty cool. The article talks about using storybook.js, but I'd love to see it used with clojure.spec. The latter is such a nice way to vet business logic with domain experts.
It is so cool to see how far things have come since ClojureScript first worked with React Native in 2015. Krell is the best REPL for this IMHO, and it does this largely by getting out of your way. :)
Who should I be sponsoring on Github to help get documentation for Krell with https://microsoft.github.io/react-native-windows/ ?
I read this article recently and tried Krell, cool stuff.
I just finished writing a Clojure AI book (free PDF download on my web site) and the idea of writing iOS apps in ClojureScript is enticing. Anyone have Apple App Store issues?
No App Store issues as far as I know.
Indeed, try Replete for example, in the iOS and macOS App Stores (https://replete-repl.org).
I've also had a separate commercial in the iOS App Store based on ClojureScript since 2014. (This pre-dated React Native, even, and is based on Goby.)
David and Mike, thanks for the confirmation.
This is great, really interesting