Fork me on GitHub

Newbie question: let's say I'm using only shadow-cljs and reagent, how do I hook up TailwindCSS to automaticaly process my css files (and trigger live reload etc)? Do I still need to use something like webpacker/browserify?


we just commited the processed tailwind css to our repo and use vanilla css in our app, can recommend


> shadow-cljs currently provides no support for directly compiling CSS but the usual tools will work and should be run separately. Just make sure the output is generated into the correct places.


but I’d recommend trying without an extra css compilation step at least in dev


I just have postcss setup separately and shadow-cljs will hot-reload it whenever it changes but knows nothing else about CSS


Okay thanks!


I'll do it the simpler way with separate processing

dhale00:04:42 At about two minutes into the video, helped me do this.


I'm using a third party npm library in my project (BabylonJS) and the compilation breaks if I try to update it to the latest version. The offending typescript code does this: public dispose(disposeAll = true): void { super.dispose(disposeAll); if (this._depthRenderer && disposeAll) { delete this._depthRenderer.getDepthMap().getScene()?._depthRenderer[this._depthRendererId]; this._depthRenderer.dispose(); this._depthRenderer = null; } } and the error I get is: "Invalid delete operand. Only properties can be deleted." If I understand correctly the issue is the usage of the "?." operator together with "delete" and it can be fixed by using an if statement instead. However I'd rather avoid patching the library. Do I have other options here like maybe a compiler flag to pass to shadow-cljs ?


shadow-cljs does not support typescript so you are looking at the wrong code


look at the code that is actually getting included


not the typescript sources. npm likely contains the transpiled code.


DepthReducer.prototype.dispose = function (disposeAll) { if (disposeAll === void 0) { disposeAll = true; } var _a;, disposeAll); if (this._depthRenderer && disposeAll) { if(this._depthRenderer.getDepthMap().getScene()) delete this._depthRenderer.getDepthMap().getScene()._depthRenderer[this._depthRendererId]; this._depthRenderer.dispose(); this._depthRenderer = null; } };


this is the corresponding JS code


either thats an invalid use of delete or a bug in the closure compiler


not much I can do in shadow-cljs


looks fine to me, dunno why it complains


wouldn't be the first time the closure-compiler found an actual bug in a library though


so this might actually be invalid and just nobody ever runs into that actual code


yes, very possible indeed. I'll try to convince the library authors to patch it then.


Can the version of the closure compiler used by shadow-cljs be changed ?


Sorry I realize the JS code above is not the offending one. It's the code I get after manually patching it. The offending code is:


DepthReducer.prototype.dispose = function (disposeAll) { if (disposeAll === void 0) { disposeAll = true; } var _a;, disposeAll); if (this._depthRenderer && disposeAll) { delete ((_a = this._depthRenderer.getDepthMap().getScene()) === null || _a === void 0 ? void 0 : _a._depthRenderer[this._depthRendererId]); this._depthRenderer.dispose(); this._depthRenderer = null; } };


right yeah that looks invalid

👌 4
Felipe Marques17:04:24

I'm playing with the lifecycle-hooks. And putting in the shadow-cljs.edn the following hook: {:devtools {:after-load my-devtools/reload}. But the hook is not called (`reloading code but no :after-load hooks are configured!`). I imagine that because I'm not requiring my namespace (`my-devtools`) anywhere in my code it is not running the function. Because, when I add a require into my main-file it runs the hook. Is this the expected behavior? I would think that shadow-cljs would require que namespace specified in the devtools.


it is expected that the namespaces are actually requireed by you


otherwise you should use :devtools {:preloads [your.ns.with-hooks]}


and in there do (defn ^:dev/after-load the-hook [] ...)


not sure what you mean by requiring it runs the hook


because that only happens if you actuall call the hook yourself

Felipe Marques17:04:47

Oh, sorry, I wasn't clear. When I add (:require [my-devtools]) at some file that is compiled and loaded by shadow and then trigger the reload by editing some file, the hook runs.


I guess it could add the namespaces to the build automatically but typically people have the hooks directly in the main ns

Felipe Marques17:04:07

humm, the hook I'm injecting is hooks that I use in my personal development flow. I'm injecting it dynamically by loading the config-map, editting it and then giving it to shadow to watch it. The other developers in the project don't use these same hooks as I do. That is why I don't put these hooks in the main ns.

Felipe Marques17:04:23

Using the preloads worked well for me (just tried it), don't know if it is necessary to add the namespaces to the build automatically. Maybe put in the documentation that the namespace must be required somewhere


you can do shadow-cljs watch app --config-merge "{:devtools {:preloads [hooks.that.only.i-want]}"

Felipe Marques17:04:00

yes, that is basically what I'm doing, but I'm doing it inside a clojure file

Felipe Marques17:04:09

I start the server and the watch command through clojure using the shadow.cljs.devtools.api .

Felipe Marques17:04:32

This is the function that I use.

(defn watch-with-profile
  [build-id profile]
  (println "Running " build-id " with profile " profile)
  (-> (shadow.config/get-build! build-id)
      (assoc :profile profile)


you can also do the config merge there


(shadow.api/watch :the-build {:config-merge [{:devtools {:preloads '[the.extra]}}]})


but your way works too

Felipe Marques17:04:07

oh, didn't know that shadow.api/watch had this option, cool!

Felipe Marques17:04:29

Thanks for the help! 😄


Hey all, I'm trying to run tests in my shadow-cljs project via the CLI. I've created a build called :cljs-tests with the following config:

{:target :node-test
            :js-options {:node-modules-dir "../"}
            :output-to "out/node-tests.js"
            :autorun true
From the documentation, it's my understanding that I can specify a main as the entry point to running the tests. For now, I just have that hardcoded to a , which just invokes cljs.test/run-tests:
(defn start []
In CLI, I'm running npx shadow-cljs compile cljs-tests . The process outputs "Compiling..." for a while, then spits out this error:
aborted par-compile, [ "my_app_name/events_test.cljs"] still waiting for #{}
{:aborted [ "my_app_name/events_test.cljs"], :pending #{}}
ExceptionInfo: aborted par-compile, [ "my_app_name/events_test.cljs"] still waiting for #{} (compiler.clj:854) (compiler.clj:819) (compiler.clj:937)
	clojure.core/apply (core.clj:665)
	clojure.core/with-bindings* (core.clj:1973)
	clojure.core/with-bindings* (core.clj:1973)
	clojure.core/apply (core.clj:669)
	clojure.core/bound-fn*/fn--5734 (core.clj:2003) (
	java.util.concurrent.ThreadPoolExecutor.runWorker (
	java.util.concurrent.ThreadPoolExecutor$ ( (
Do you know what I might be missing?


if you are just calling run-tests then you don't need :main at all because its what it does by default?


Ah okay, that's good to know. I am getting some feedback when I run w/o the main option. Thanks


:main applies to :node-script only


for :node-test you'd use :runner-ns if a custom runner is needed


:main just confuses the compiler I guess


should filter that out so feel free to open a ticket about that


actually nevermind ... :main should work fine


dunno why it doesn't


Awesome thanks for the additional detail. The documentation might be a little out of date re: :main for node-test target. I can send a PR if that's alright?


Oh I see, hmm


I'm getting an error that window is not defined, which makes sense in a node runtime. Wondering if I should try to mock window or use the :browser-test target. I'm not performing any UI tests, just business rule logic in CLJS, but cljs/shadow-cljs seem to be pulling in all of my NPM dependencies, many of which reference window


shadow-cljs doesn't pull in anything using window if you use :node-test


must be your code doing that


(or your dependencies)


use browser-test or karma if you need browser stuff


thank you. karma seems to be working well


im wondering if i can start a shadow-cljs watcher + karma runner in a single terminal. the example in the documentation runs compiles, then runs karma. i can run them from 2 terminals no prob


shadow-cljs does not run karma for you no

Felipe Marques12:04:43

You can use the :ns-regexp to get only the tests and which will probably not depend on the window object.


Thanks Felipe! I'll give that a try

👍 4