This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-02-09
Channels
- # announcements (3)
- # babashka (17)
- # beginners (75)
- # calva (43)
- # cider (1)
- # clj-kondo (54)
- # cljdoc (8)
- # cljs-dev (70)
- # clojure (83)
- # clojure-europe (27)
- # clojure-nl (4)
- # clojure-norway (4)
- # clojure-spec (8)
- # clojure-uk (13)
- # clojured (2)
- # clojurescript (47)
- # community-development (4)
- # conjure (2)
- # cursive (3)
- # datomic (5)
- # emacs (5)
- # events (3)
- # fulcro (13)
- # graalvm-mobile (19)
- # helix (2)
- # introduce-yourself (1)
- # jobs (2)
- # jobs-discuss (28)
- # kaocha (9)
- # livestream (11)
- # malli (15)
- # meander (24)
- # nextjournal (8)
- # off-topic (26)
- # pathom (1)
- # pedestal (8)
- # polylith (2)
- # portal (31)
- # re-frame (4)
- # reagent (10)
- # reitit (8)
- # remote-jobs (3)
- # sci (1)
- # shadow-cljs (66)
- # spacemacs (20)
- # testing (6)
- # vim (15)
- # xtdb (7)
Is anyone using shadow-cljs with some sort of task runner? I was hoping to use one command to run the build/watch and then run my nodescript outputted by shadow-cljs. I'd normally do this with GulpJS. Are people using tools.deps to do this?
I have a two part project (server and cli), it would be cool to run the build for both in parallel and start cli/server files so I can connect to their js runtimes for repl use.
npm-run-all as setup in this project is what I usually use https://github.com/jacekschae/shadow-cljs-tailwindcss/blob/main/package.json
Thanks. I haven't heard of it. Seems like I wouldn't be able to get the outcome I wanted for target node-scripts since I need to wait until the build completes before running the script. That is a good workflow for a browser app, though.
What could be the cause of a situation where shadow-cljs does not complain about a missing ^js
but that tag not being present still results in an incorrectly minified name?
My guess is that name was used in e.g. Closure library. Are there any other potential causes?
(set! *warn-on-infer* false)
turns everything off, just in case that is in the file?
No, I never use that set!
.
Here's the code, with some crud removed:
(defn replace-track-source! [^js playlist track-name src]
(loop [tracks (.-tracks playlist)]
(when-first [track tracks]
(if (= (.-name track) track-name)
(do
(-> (to-audio-buffer src playlist)
(.then (fn [audio-buffer]
(set! track -src audio-buffer)
(.setBuffer track audio-buffer)))))
(recur (next tracks))))))
:advanced
renamed .setBuffer
.hmm dunno. it doesn't warn about anything that already has externs, setBuffer
seems like it may exist
you sure its actually that thing getting renamed? I mean actually confirmed with :pseudo-names
?
Yep, did a release build with --debug
- it became .$setBuffer$
. Adding ^js
in front of track
in the when-first
form fixes that.
:compiler-env
-> :cljs.analyzer/namespaces
-> your.ns
-> :shadow/js-*
should contain it
externs inference happens mostly in the cljs compiler. so maybe try with the regular CLJS compiler too
Yep, it's neither in the externs file nor in the inspect UI.
Some other fields are also not in the inspect UI - I suspect because they were first picked up in some other ns? E.g. .then
is not there, even though it definitely works, but .resolve
is there.
My understanding of externs is very limited indeed. :) I see. Anyway, I'll try to stumble around with a proper debugger and see what I can find.
Seems like indeed a CLJS issue - the tags returned for track
by the analyzer are any
and clj-nil
.
Ah, crap. Pretty sure I figured it out. Notice that when-first
- it gets expanded into essentially (let [track (first (seq tracks))] ...)
. And seems like that seq
makes CLJS analyzer forget about the ^js
tag.
When setting :compiler-options {:externs ["/app/components/user/payment.js"]
i get this:
[:app] Compiling ...
[BABEL] Note: The code generator has deoptimised the styling of /Users/simonchristensen/Documents/Developer/movenation/calculator/node_modules/@firebase/firestore/dist/index.esm2017.js as it exceeds the max of 500KB.
{:type :missing-externs, :extern "/app/components/user/payment.js", :shadow.build.log/level :warn}
{:type :missing-externs, :extern "/app/components/user/payment.js", :shadow.build.log/level :warn}
[:app] Build completed. (3727 files, 3616 compiled, 0 warnings, 95.37s)
fixed by removing /
prefix: :compiler-options {:externs ["app/components/user/payment.js"]
But now this file is not supported since, the js version used is too new:
JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT_2015 mode or better: modules. at EXTERNS:app/components/user/payment.js line 1 : 0
JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT_2015 mode or better: modules. at EXTERNS:app/components/user/payment.js line 2 : 0
JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT_2015 mode or better: const declaration. at EXTERNS:app/components/user/payment.js line 5 : 0
JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT_2015 mode or better: object destructuring. at EXTERNS:app/components/user/payment.js line 5 : 6
JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT_2015 mode or better: const declaration. at EXTERNS:app/components/user/payment.js line 6 : 0
JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT_2015 mode or better: const declaration. at EXTERNS:app/components/user/payment.js line 7 : 0
JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT_2015 mode or better: modules. at EXTERNS:app/components/user/payment.js line 9 : 0
what does that mean js version used is too new? there is no point in using new features in externs?
For the :browser-test
target, is there any way to influence the path it uses in the index.html file?
<script src="/js/test.js">
(I mean the /js/test.js
there, I'd like to change that path)
I tried setting :asset-path
, like one would for the :browser
target, but that was ignored.
I've got a library with the :node-library
target that has one basic interface point between the clojurescript and javascript worlds. I use a deftype
with Object
methods to provide the javascript-side interface, e.g.,
(deftype Mediator
Object
(opA [this] ...)
(opB [this in] ...)
...)
When done this way, I get the Cannot infer target type
warnings on the deftype expression. I set :infer-externs :auto
in compiler options, which does not fix the warnings. The warnings do go away when instead when I do deftype ^js Mediator
, but that turns the Mediator type into a POJO requiring js-style operations on the object inside the methods (e.g., set!
works but not assoc
). This is fine, and I can live with it.
I am curious, however, about best practices for this use case. What is the best way to create a javascript object interface to clojurescript code with shadow-cljs? Will the javascript methods (e.g., opA
and opB
) be externed properly this way under advanced compilation? And is it necessary to make the mediating type a mutable POJO or is it possible to have clojurescript data that is treated as an opaque object on the javascript side? I'd appreciate hearing what other people do in this situation. Thanks!this really is hard to answer if you take out the part generating inference warnings?
@thheller (assuming you are answering me, please disregard if not) Do you mean that the first deftype (without ^js
) should not generate inference warnings?
I would add that the inference warnings are still emitted even if I treat the this
as a POJO in the methods.
@genovese you have given only partial of the code and the error message so I do not know what you are talking about. you get an inference warning on what exactly?
what does "deftype ^js Mediator, but that turns the Mediator type into a POJO requiring js-style operations on the object" mean? I do not understand what that means?
deftype
with Object
methods are completely fine but without knowing more about what exactly you are doing its hard to give a accurate answer
Sorry. First, here's an example of the message:
26 | (deftype Mediator [frame options env]
-------^------------------------------------------------------------------------
Cannot infer target type in expression (. (. MathLingo -prototype) -render)
--------------------------------------------------------------------------------
27 | Object
28 | (render [this]
29 | (str "TBD" (process frame))))
With ^js
, there inference error goes away.
On the second point, you're right, my mistake. I did a deftype here, not a defrecord. I had done it earlier with defrecord and then changed it with the type hint but foolishly ignored that (even as I typed it), so of course assoc no longer worked. Apologies.
The remaining questions are why is the ^js needed, and is there a better way to achieve this goal than what I'm doing here. Thanks!Sorry, name changed. Should be (. Mediator -prototype)
. Not really on my game today 🙂
Hmm...not sure what to make of that. Here's my config
{:source-paths
["src/dev"
"src/main"
"src/test"]
:dependencies
[[better-cond "2.1.0"]
[binaryage/oops "0.7.0"]
[camel-snake-kebab "0.4.2"]
[data.deque "0.1.0"]
[instaparse "1.4.10"]
[metosin/potpuri "0.5.3"]
[com.rpl/specter "1.1.3"]
[net.cgrand/xforms "0.19.2"]
[org.clojure/algo.monads "0.1.6"]
[org.clojure/core.match "1.0.0"]
[org.clojure/test.check "1.1.1"]]
:builds
{:main {:target :node-library
:output-to "out/mathlingo.js"
:exports {:createParser mathlingo.core/create-parser}
:compiler-options {:infer-externs :auto}
:devtools {:repl-pprint true}}
:test {:target :node-test
:output-to "out/node-tests.js"
:ns-regexp "-test$"
:autorun false}}
:nrepl {:port 8777}
:open-file-command ["emacsclient" "-n" ["+%s:%s" :line :column] :file]}
It does not produce warnings for me at the repl, but when it compiles it does.
2.6.12 What could I be doing differently? I can try it in a raw project, but I don't see what I can tweak otherwise.
=== Version
jar: 2.16.12
cli: 2.16.12
deps: 1.3.2
config-version: 2.16.12
=== Paths
cli: /.../node_modules/shadow-cljs/cli/dist.js
config: /.../shadow-cljs.edn
project: /...
cache: .shadow-cljs
=== Java
openjdk version "15.0.1" 2020-10-20
OpenJDK Runtime Environment (build 15.0.1+9-18)
OpenJDK 64-Bit Server VM (build 15.0.1+9-18, mixed mode, sharing)
I don't know either. there is nothing to tweak. If you have a reproducible case I'm happy to take a look but so far this all looks fine
OK, thanks. I'll clear the cache and start again. And I'll assume all is ok. I appreciate the help.
you can always turn off inference warnings by (set! *warn-on-infer* false)
before the deftype
or so and turn it back on again after
Great, that will be more pleasant if it continues.