Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

0 votes
in ClojureScript by
Tools like Figwheel normally have to compose over the compiler
in-order to capture important build signals (ie. compile finished,
exception thrown, syntax warnings, and perhaps compile start). This is
a significant coupling and it prevents them from reusing the built-in
watching and compiling facilities that are already available.

I'd like to propose firing events for these important build signals.
This would enable tooling like Figwheel to decouple itself from
whatever is triggering a compile in the first place.

Providing this signal would also go a long way towards making
cljs.main be the parent tool in the CLJS toolchain.

I also propse that the Object that fires these events to be attached
to the {{cljs.env/*compiler*}} in some fashion. The {{cljs.env/*compiler*}} is
already present everywhere this information is needed, and is also the
datastructure that represents/holds all the information for a
particular "build" in the compiler.

The solution could be as easy as adding data or meta-data to the map held in
{{cljs.env/*compiler*}} such as


 :compile-data {:finished-at timestamp
                :warnings [...]
                :exception (on exception)}


And tools could add watches to the {{env/*compiler*}} and wait for
these keys to be set.

This is certainly a simple solution. The downside of this may be
slowing down the compiler because changes/swaps! to the
{{env/*compiler*}} occur quite often and tools will checking for these
"flags" to be set on every change. Tools would have to ensure that the
processing they perform on the compiler thread is quick and to the
point or they risk slowing down the compiler. This may be a non-issue
but is worth to mentioning.

Another approach is to embed a simple observable into the
{{env/*compiler*}} data and fire events on this observable for the
significant build events.

Or one could simply extend the {{env/*compiler*}} atom with this
Observable.

There are many of solutions; the important thing is to provide the
information so that tools will have it available to them.

The great thing about using the {{env/*compiler*}} as a vehicle, is that
tools can add listeners for the events on the {{env/*compiler*}} before
they call build or they can add listeners to the {{env/*compiler*}} that is bound
and present on the compiler thread from a macro that is executed from
the REPL or even a compiled file. In other words tool writers would be
able to pass listeners to the compile process or add listenerers from
within it.

This would be pretty darn flexible and powerful.

2 Answers

0 votes
by

Comment made by: dnolen

I don't like the idea of writing events to the state atom. The warning handler pattern seems fine to me, we should just generalize that.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJS-2617 (reported by bhauman)
...