Shadow CLJS API
Our first project is now in place. In this chapter, we'll learn how to build and run it. We'll also explore some other build targets and explore Shadow with Reagent, a ClojureScript wrapper to React.
Shadow offers many helpers to compile and develop your app, but we only need to know about three methods right now:
compile
watch
release
compile
and watch
are similar in scope. Both of them convert the ClojureScript code to JavaScript code based on the build target. The only difference is that watch
re-compiles each time a file on the source path changes.
The JavaScript code produced by both compile
and watch
is inspectable, ie it's not uglified or minified.
The release
method bundles the code for production. It applies advanced optimizations, minification, and uglification.
ClojureScript relies on Google's Closure Library (GCP) to transform CLJS to JavaScript. GCP is Google's in-house alternative for Webpack and was open-sourced over ten years ago. All major Google apps including Gmail rely on GCP.
GCP has got nothing to do with Clojure. The term "Closure" in GCP might be a little confusing. It's not a typo. GCP has a Closure with an "s".
Start watch
ing#
We are ready to start our first build. We have set up our configuration, installed Shadow, and created a namespace. Our main
function prints "Hello World".
To start Shadow watch
, we need to issue the watch
command with a build target:
yarn shadow-cljs watch :script
# or npx shadow-cljs watch :script
The :script
is the name of our build target, defined in Shadow config.
When you run the watch
command for the first time, Shadow will install the required dependencies.
Your output will be similar to:
$ yarn shadow-cljs watch :script
yarn run v1.21.1
shadow-cljs - updating dependencies
Retrieving thheller/shadow-cljs/2.10.15/shadow-cljs-2.10.15.pom from https://repo.clojars.org/
Retrieving cider/piggieback/0.5.0/piggieback-0.5.0.pom from https://repo.clojars.org/
Retrieving thheller/shadow-cljsjs/0.0.21/shadow-cljsjs-0.0.21.jar from https://repo.clojars.org/
shadow-cljs - dependencies updated
If everything goes well, you should see some log statements saying that the build completed and the nREPL server is running:
shadow-cljs - server version: 2.10.15 running at http://localhost:9630
shadow-cljs - nREPL server started on port 9000
shadow-cljs - watching build :script
[:script] Configuring build.
[:script] Compiling
[:script] Build completed. (76 files, 75 compiled, 0 warnings, 18.76s)
Shadow compiled 76 files, started the nREPL on port 9000 as defined in the config, and also started a server on port 9630. We have learned about nREPL already. The other server offers a web-based dashboard that gives an overview of all builds and runtimes. It also provides an interface to Shadow Inspect, which is a smart logging system, similar to Chrome Dev Tools.
Running the script#
At this point, your ClojureScript code is compiled to a Node script in build/node-script/core.js
. You can inspect this code as it's JavaScript, but it might not make much sense. The :node-script
target bundles everything into a single file, which allows for easy distribution at the cost of readability.
However, we can simply run the compiled Node script:
# in the first-project directory
node build/node-script/core.js
"Hello World"
shadow-cljs - #3 ready!
You might notice that the process doesn't terminate. This is because Shadow in watch
mode allows for some hooks that can execute your code in the Node environment each time you make a change. For now, you can simply press Ctrl+C
or Cmd+C
to exit.
Try changing the message in core.cljs
to "Hello World 2". You should notice that as soon as you save that file, Shadow rebuilds the script.
Making script production-ready#
So far the scripts we built with watch
were for the development environment.
The release
command builds the script in production mode. It uglifies, minifies, and applies optimizations to JavaScript output. To build our :script
target run the following command:
This page is a preview of Tinycanva: Clojure for React Developers