Fork me on GitHub
#shadow-cljs
<
2020-04-11
>
solf06:04:33

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?

mkvlr07:04:42

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

mkvlr07:04:40

> 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.

mkvlr07:04:50

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

thheller08:04:43

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

solf11:04:11

Okay thanks!

solf11:04:00

I'll do it the simpler way with separate processing

dhale00:04:42

https://youtu.be/_CTTbC6owS0 At about two minutes into the video, helped me do this.

sylvain15:04:19

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 ?

thheller15:04:54

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

thheller15:04:07

look at the code that is actually getting included

thheller15:04:21

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

sylvain15:04:28

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

sylvain15:04:54

this is the corresponding JS code

thheller15:04:37

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

thheller15:04:42

not much I can do in shadow-cljs

thheller15:04:11

looks fine to me, dunno why it complains

thheller15:04:37

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

thheller15:04:55

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

sylvain15:04:36

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

sylvain15:04:58

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

sylvain15:04:12

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:

sylvain15:04:21

DepthReducer.prototype.dispose = function (disposeAll) { if (disposeAll === void 0) { disposeAll = true; } var _a; _super.prototype.dispose.call(this, 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; } };

thheller16:04:04

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.

thheller17:04:32

it is expected that the namespaces are actually requireed by you

thheller17:04:51

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

thheller17:04:07

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

thheller17:04:05

not sure what you mean by requiring it runs the hook

thheller17:04:15

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.

thheller17:04:52

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

thheller17:04:34

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)
      set-devtools-hooks
      shadow.api/watch))

thheller17:04:05

you can also do the config merge there

thheller17:04:32

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

thheller17:04:57

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! 😄

Alex22:04:00

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
            :main my-app-name.events-test/start}
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 my-app-name.events-test/start , which just invokes cljs.test/run-tests:
(defn start []
  (cljs.test/run-tests))
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, [:shadow.build.classpath/resource "my_app_name/events_test.cljs"] still waiting for #{my-app-name.events-test}
{:aborted [:shadow.build.classpath/resource "my_app_name/events_test.cljs"], :pending #{my-app-name.events-test}}
ExceptionInfo: aborted par-compile, [:shadow.build.classpath/resource "my_app_name/events_test.cljs"] still waiting for #{my-app-name.events-test}
	shadow.build.compiler/par-compile-one (compiler.clj:854)
	shadow.build.compiler/par-compile-one (compiler.clj:819)
	shadow.build.compiler/par-compile-cljs-sources/fn--12733/iter--12755--12759/fn--12760/fn--12761/fn--12762 (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.FutureTask.run (FutureTask.java:264)
	java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1128)
	java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:628)
	java.lang.Thread.run (Thread.java:834)
Do you know what I might be missing?

thheller22:04:26

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

Alex22:04:22

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

thheller22:04:50

:main applies to :node-script only

thheller22:04:02

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

thheller22:04:17

:main just confuses the compiler I guess

thheller22:04:39

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

thheller22:04:28

actually nevermind ... :main should work fine

thheller22:04:33

dunno why it doesn't

Alex22:04:39

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?

Alex22:04:43

Oh I see, hmm

Alex23:04:27

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

thheller23:04:58

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

thheller23:04:04

must be your code doing that

thheller23:04:31

(or your dependencies)

thheller23:04:49

use browser-test or karma if you need browser stuff

Alex00:04:15

thank you. karma seems to be working well

Alex00:04:00

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

thheller07:04:00

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. https://shadow-cljs.github.io/docs/UsersGuide.html#_testing

Alex03:04:52

Thanks Felipe! I'll give that a try

👍 4