ClojureScript: NPM in Figwheel in 60 Seconds
Aug 11, 2017 17:11 · 467 words · 3 minutes read
Update 2017-08-22
Looks like the latest version of Clojurescript (1.9.908) broke something! If you see an error that looks like this:
…then you’ll have to downgrade Clojurescript to version 1.9.854. In the
:dependencies
block near the top of your project.clj
, modify the Clojurescript
version to look like:
[org.clojure/clojurescript "1.9.854"]
After that, restart figwheel and you should be good to go!
Thanks to Gene Kim for pointing this out!
Original Post
The ClojureScript team continues to delight!
The last time we set up a new Figwheel project to demo Javascript/ClojureScript interop, we had to:
- Build ClojureScript from Scratch
- Update dependency versions in the Figwheel template
- Shim
process.env/NODE_ENV
so the:closure-defines
could find it - Add our shim to
:preloads
so NPM libs could referenceNODE_ENV
Now, none of this is necessary!
Starting a ClojureScript/Figwheel project from scratch and configuring it to use Javascript modules from NPM is now a 1 minute process. One minute!
Step 1: Start a new Fighweel Project
$ lein new figwheel splort
Step 2: Modify project.clj
We need to add NPM dependencies, install them, and tell the closure compiler what
our NODE_ENV is. We do that by adding the following three lines to the :compiler
section of our "dev"
build in :cljsbuild
:
:closure-defines {process.env/NODE_ENV "development"}
:npm-deps {:react "15.6.1" :react-dom "15.6.1"}
:install-deps true
Then, in the "min"
section:
:closure-defines {process.env/NODE_ENV "production"}
:npm-deps {:react "15.6.1" :react-dom "15.6.1"}
:install-deps true
Step 3: Use React (natively!) in ClojureScript
Paste the following into src/splort/core.cljs
:
(ns splort.core
(:require [react :refer [createElement]]
[react-dom :refer [render]]))
(js/console.log "Node enviornment is" process.env/NODE_ENV)
(def appDiv (.getElementById js/document "app"))
(render
(createElement "h1" nil "Hello, World!")
appDiv)
Step 4: Build it!
$ lein figwheel
If everything goes well, the site should render like so:
Conclusion
It hasn’t even been two weeks since the first Figwheel/NPM interop tutorial went live, and the ClojureScript community has already reduced the friction for JS interop by an order of magnitude.
I don’t think it can be overstated that you get all the benefits of the Google Closure compiler, out of the box, for free. Dead code elimination, Javascript compilation, better production assets than you can get with hours of Webpack tuning, and with all the benefits of Clojure to accompany it.
With Gratitude
All of this is made possible thanks to the hard work of the ClojureScript community.
Special thanks to:
- David Nolen for submitting CLJS 2280 mere hours after reading the previous tutorial
- Bruce Hauman for his patience and guidance with PR 588
- Mike Fikes for being the first person to retweet the first tutorial, giving it the visibility necessary to affect positive change
I’ve had such a positive experience interacting with members of the ClojureScript community. I’m convinced that it’s the excellent people (in addition to the excellent tooling) that makes Clojure such a delightful language to work with.