# Problem using malli clojurescript instrumentation and shadow-cljs

**URL:** https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612
**Category:** Troubleshooting
**Tags:** clojurescript
**Created:** [February 6, 2022, 7:27am UTC](https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612 "2022-02-06T07:27:17Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![DrLjotsson](https://clojureverse.org/user_avatar/clojureverse.org/drljotsson/32/2602_2.png) [@DrLjotsson](https://clojureverse.org/u/DrLjotsson)
#### Post date: [February 6, 2022, 7:27am UTC](https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612/1 "2022-02-06T07:27:17Z")

</div>

I’m trying out the new clojurescript instrumentation in `malli 0.8.0` and am getting into issues with hot-reload and `shadow-cljs`. I’ve battled back-and-forth with this for a while so I’m not quite sure I’ve understood the problem correctly.

Aim: To be able to call `malli.instrument.cljs/instrument!` from another namespace than the ones where `m/=>` is called.

Problem: Changed instrumentations do not take effect, not even after quitting and restarting `shadow-cljs watch app`. I have to delete the `.shadow-cljs` directory and then restart the watch.

Hypothesized reason: Since the `malli.instrument.cljs/instrument!` is a macro, it generates the instrumentations at compile time. Since the namespace where it is called is not recompiled when I change the instrumentations (in other namespaces), the changed instrumentations are not included when the macro is expanded. Restarting `shadow-cljs watch app` doesn’t help since the build is cached.

Potential solution: Can I force `shadow-cljs` to recompile the namespace where `malli.instrument.cljs/instrument!` is called whenever any other namespace changes? Or should I go about this some other way?

---

<div class="post-metadata">

### Author: ![thheller](https://clojureverse.org/user_avatar/clojureverse.org/thheller/32/534_2.png) [@thheller](https://clojureverse.org/u/thheller)
#### Post date: [February 6, 2022, 8:23am UTC](https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612/2 "2022-02-06T08:23:20Z")

</div>

Instrumentation is kinda tricky since it can affect all namespaces. The best way to go about this is via `:preloads` with a custom ns created for it.

```auto
(ns my.app.preload
  {:dev/always true}
  (:require
    [my.app] ;; must require all namespace here that potentially get instrumented
    [malli.instrument.cljs :as mi]))

(mi/instrument!)

```

The in your build config `:devtools {:preloads [my.app.preload]}`.

The `{:dev/always true}` always metadata on the `ns` ensures that this namespace is always recompiled. Although note that this can make your build a lot slower. It isn’t strictly necessary if the macro doesn’t emit changing code but since there is no reliable way to know what the macro does (from the shadow-cljs side) it might be best to always run it.

The `my.app` require ensures that the preload is actually compiled after all your app namespaces have been compiled. I know “preload” isn’t the best name here but you must do this to ensure that other namespaces aren’t still compiling when the macro runs.

---

<div class="post-metadata">

### Author: ![DrLjotsson](https://clojureverse.org/user_avatar/clojureverse.org/drljotsson/32/2602_2.png) [@DrLjotsson](https://clojureverse.org/u/DrLjotsson)
#### Post date: [February 6, 2022, 9:49am UTC](https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612/3 "2022-02-06T09:49:18Z")

</div>

Thanks, works! I should of course have tried that but I thought that `^:dev/always` only meant that the namespace was reloaded (not recompiled).

---

<div class="post-metadata">

### Author: ![DrLjotsson](https://clojureverse.org/user_avatar/clojureverse.org/drljotsson/32/2602_2.png) [@DrLjotsson](https://clojureverse.org/u/DrLjotsson)
#### Post date: [February 6, 2022, 12:25pm UTC](https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612/4 "2022-02-06T12:25:05Z")

</div>

Works perfectly in my dev environment (I think). But when I try the exact same setup for my tests (pre-load which requires my core test namespace), I get all kinds of strange errors. Sometimes just some functions are instrumented, and other times `mi/instrument!` results in a js error claiming that an instrumented function is `undefined`, although tests against work fine.

Can this be related to how test namespaces are loaded? There is no `{:modules {:main {:entries [...]}}]` in the test configuration, and the user’s guide suggests that there shouldn’t be one.

EDIT: Tried to enter the core test namespace as main module in `:test` but that led to a compile error.

---

<div class="post-metadata">

### Author: ![dvingo](https://clojureverse.org/user_avatar/clojureverse.org/dvingo/32/3041_2.png) [@dvingo](https://clojureverse.org/u/dvingo)
#### Post date: [February 15, 2022, 2:48pm UTC](https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612/5 "2022-02-15T14:48:56Z")

</div>

> [@DrLjotsson](#):
>
> get all kinds of strange errors. Sometimes just some functions are instrumented, and other times `mi/instrument!` results in a js error claiming that an instrumented function is `undefined` , although tests against work fine.

These are tricky because the way instrumentation works is that it `(set!)`s the javascript variable ([malli/src/malli/instrument/cljs.clj at 2398df55ee806e25592fabf4d0c642ee3a2b233f · metosin/malli · GitHub](https://github.com/metosin/malli/blob/2398df55ee806e25592fabf4d0c642ee3a2b233f/src/malli/instrument/cljs.clj#L42))  
so depending on the order of how code is evaluated there can be odd behavior.

Are you running tests in a REPL or just as compiled asset?

---

<div class="post-metadata">

### Author: ![DrLjotsson](https://clojureverse.org/user_avatar/clojureverse.org/drljotsson/32/2602_2.png) [@DrLjotsson](https://clojureverse.org/u/DrLjotsson)
#### Post date: [February 16, 2022, 1:55pm UTC](https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612/6 "2022-02-16T13:55:10Z")

</div>

Thanks @dvingo. Yes, I guess that the order of evaluation in tests is not predictable as it is when you are running a “regular” Shadow-CLJS app. I’m using Shadow-CLJS’ test runner, so compiled and run through the browser (not REPL). I’ve given up on getting instrumentation to work there - I don’t think it is as important though since I’m not running generative tests. It serves a purpose in development though so I get feedback if my functions don’t work in the semi-real world.

---

<div class="post-metadata">

### Author: ![dvingo](https://clojureverse.org/user_avatar/clojureverse.org/dvingo/32/3041_2.png) [@dvingo](https://clojureverse.org/u/dvingo)
#### Post date: [February 23, 2022, 5:26pm UTC](https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612/7 "2022-02-23T17:26:34Z")

</div>

If you are able to publish a repository demonstrating the weirdness, I’d like to take a look.

---

<div class="post-metadata">

### Author: ![DrLjotsson](https://clojureverse.org/user_avatar/clojureverse.org/drljotsson/32/2602_2.png) [@DrLjotsson](https://clojureverse.org/u/DrLjotsson)
#### Post date: [February 23, 2022, 8:48pm UTC](https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612/8 "2022-02-23T20:48:37Z")

</div>

Sure, I’ll see if I can make a repro, but it may take a few weeks (I only develop in my spare time).

---

<div class="post-metadata">

### Author: ![system](https://clojureverse.org/uploads/default/original/2X/5/51079bf9e4b7d9466242c06cf1e43b9f8bd6da14.png) [@system](https://clojureverse.org/u/system)
#### Post date: [August 25, 2022, 8:49am UTC](https://clojureverse.org/t/problem-using-malli-clojurescript-instrumentation-and-shadow-cljs/8612/9 "2022-08-25T08:49:25Z")

</div>

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.
