The ClojureScript compiler plugin helps you visualize and move aruod your ClojureScript compilations recordings by representing them as an interactive graph.
It can help you troubleshoting the compiler, develope it or just help you learn how it works.
Requires FlowStorm >= 4.2.0
Clone the ClojureScript compiler somewhere :
git clone [email protected]:clojure/clojurescript.git
Add an extra alias to the deps.edn file :
{...
:aliases
{...
:storm {:classpath-overrides {org.clojure/clojure nil}
:extra-deps {com.github.flow-storm/flow-storm-dbg {:mvn/version "4.2.0"}
com.github.flow-storm/clojure {:mvn/version "1.12.0-4"}
com.github.flow-storm/flow-storm-cljs-compiler-plugin {:mvn/version "1.0.0-beta"}}
:jvm-opts ["-Dvisualvm.display.name=CLJSCompiler"
"-Dclojure.storm.instrumentEnable=true"
"-Xms5000m" "-Xmx5000m"
"-Dflowstorm.startRecording=false"
"-Dclojure.storm.instrumentOnlyPrefixes=cljs."
"-Dflowstorm.jarEditorCommand=emacsclient -n +<<LINE>>:0 <<JAR>>/<<FILE>>"
"-Dflowstorm.fileEditorCommand=emacsclient -n +<<LINE>>:0 <<FILE>>"
"-Dflowstorm.theme=dark"
"-Dflowstorm.plugins.namespaces=flow-storm.plugins.cljs-compiler.all"]}}}
You can see the latest dependency for the plugin here
Start a repl with the new :storm
alias and start the debugger UI with recording stopped (default):
$ clj -A:storm
...
user=> :dbg
Now convert that repl into a ClojureScript one :
user=> ((requiring-resolve 'cljs.main/-main) "--repl")
ClojureScript 0.0.398608251
cljs.user=>
A browser window should popup, and you should now have a ClojureScript repl. Try to evaluate some forms to make sure everything is working smoothly.
Let's say you want to understand the compilation of (defn sum [a b] (+ a b))
.
- First start recording on the flow storm UI
- Now evaluate the form on the ClojureScript repl
- You should see recordings poping up on the FlowStorm UI Flows tab
- You can now safely stop recording
- Go to the
ClojureScript compiler
plugin tab - Select the flow id you recorded in (0 by default) and click the refresh button
- You should see a graph rendering like in the screenshots above
The graph is composed of 4 main stages, some of them with their own sub graph.
- Reader (the output of the reader for your repl form)
- Repl wrapping (the wrapping the compiler does en every form that is typed at the repl)
- Analysis and parsing (analisys, parsing and optimizations)
- Emission (javascript code strings generation)
You can use the mouse left click for panning and the wheel for zooming.
Clicking on each stage View return
should show the return value on the right data window, while
clicking Goto return
should take you to the code stepper at that point in time.
The analysis/parsing subgraph is composed of nodes that represent calls to cljs.analyzer/analyze*
and cljs.analyzer/parse
.
The greyed out nodes are the analysis/parsing of the wrapping parts while the highlighted ones represent your form analysis and parsing, which is probably the most interesting one.
Each node shows the sub-form it is working with. Use the buttons to quickly view call arguments, return values and jumping to the code stepper at those points in time.
Analysis nodes also contains a list of the passes
which applied at that analysis instance. Double clicking on a pass will also take you
to that point in time.
The emission sub-graph is similar to the analysis one, but its nodes represent calls to cljs.compiler/emit
for a certain AST :op
.
It also contains a list of the javascript strings generated by that instance of emission. Double clicking on each strings will take you to that point in time.