This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-04-13
Channels
- # announcements (6)
- # babashka (96)
- # beginners (159)
- # calva (16)
- # cider (17)
- # clj-kondo (4)
- # cljdoc (6)
- # cljfx (3)
- # clojure (202)
- # clojure-europe (21)
- # clojure-italy (2)
- # clojure-nl (36)
- # clojure-spec (6)
- # clojure-uk (16)
- # clojurescript (29)
- # conjure (25)
- # cursive (29)
- # data-science (12)
- # datalog (18)
- # datomic (58)
- # depstar (73)
- # duct (16)
- # emacs (65)
- # events (3)
- # fulcro (8)
- # honeysql (12)
- # jackdaw (6)
- # jobs (7)
- # jobs-discuss (3)
- # kaocha (50)
- # leiningen (8)
- # lsp (14)
- # malli (83)
- # meander (34)
- # off-topic (2)
- # polylith (4)
- # proletarian (7)
- # re-frame (8)
- # releases (9)
- # remote-jobs (3)
- # shadow-cljs (101)
- # sql (1)
- # tools-deps (48)
- # vim (7)
- # xtdb (13)
- # yada (14)
is there a way to apply preloads only to some modules and not all. I am trying to create a web-worker, but the preloads assume the main thread js environment is present and are resulting in an exception when the worker starts.
@danvingo you can set :preloads
per module yes. just {:modules {:main {:init-fn
Thanks! That worked, but these are dev-time only preloads, is there a way to include them only during dev and not a release? I tried nesting them under :dev
but they aren't being included now:
{:modules {:main { :dev
;; moving to here:
{:preloads [...]} }
:worker{}}
:devtools {:after-load app.client.client-entry/refresh
:http-port 8044
:http-resource-root "public"
:http-root "resources/public"
;; moving from here
:preloads [com.fulcrologic.fulcro.inspect.preload
app.client.development-preload
com.fulcrologic.fulcro.inspect.dom-picker-preload]}}
I have been digging through old Clojurians messages and issues on Github related to connecting a repl to different runtime environments we need to deal with when doing Chrome extensions. Still unclear to me if this is possible... let alone how to do it. It seemed that @wilkerlucio mentioned that he had it working on background
and devtool
but not content-script
. Though I have not been able to get any working. Wondering what the current state of this is and whether it is worth investing any more time in trying to get it working. Seems that there is a lot of nrepl and sourcemap related issues..
Using shadowcljs$aot version, constantly seeing this error:
[:mobile] Build completed. (203 files, 91 compiled, 0 warnings, 13.29s)
Exception in thread "async-dispatch-2" java.lang.IllegalArgumentException: No implementation of method: :close! of protocol: #'clojure.core.async.impl.protocols/Channel found for class: nil
at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:583)
at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:575)
at clojure.core.async.impl.protocols$eval1077$fn__1078$G__1066__1083.invoke(protocols.clj:21)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invokeStatic(ioc_macros.clj:979)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:975)
at clojure.core.async$ioc_alts_BANG_$fn__3907.invoke(async.clj:384)
at clojure.core.async$do_alts$fn__3839$fn__3842.invoke(async.clj:253)
at clojure.core.async.impl.channels.ManyToManyChannel$fn__1491.invoke(channels.clj:265)
at clojure.lang.AFn.run(AFn.java:22)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)
@i that means you are also using a conflicting too old core.async version as a dependency
with all AOT code you basically need to have the version that the AOT code used, otherwise you'll get errors such as that
I wonder why that makes a difference. With or without aot, I thought using an old library will both fail, not aot alone.
just an artifact of how clojure AOT code works, doesn't mean the non AOT code will work. it might fail at a different point in the code and not directly on load
@grounded_sage I cannot help without seeing your config or what you are actually doing. chrome extensions are rather difficult since they do have all sorts of restrictions but the repl and hot-reload do work. I cannot tell you more since I don't know what you have tried. this is still pretty much the only "documentation" that exists https://github.com/thheller/shadow-cljs/issues/279
Here is the shadow-cljs.edn
and the manifest.edn
@thheller. Currently I get a tonne of few websocket errors that are thrown in the console and a bunch of sourcemap errors.
https://github.com/homebaseio/datalog-console/blob/extension/shadow-cljs.edn
https://github.com/homebaseio/datalog-console/blob/extension/shells/chrome/manifest.edn
Have mostly been aligning with the file structure and set up done for fulcro-inspect
so that it is easier to reference across the two and see differences.
https://github.com/homebaseio/datalog-console/blob/extension/shells/chrome/manifest.edn#L21
I can never remember the exact rules for CSP but it needs to be able to connect to localhost:9630 (the shadow-cljs instance server)
ah sorry on my local that is set to 9630. Must have been a recent change I did not push.
Okay. Seems that changing the CSP url to be the same as devtools-url
removes the ws errors that are thrown. But this makes it different to what is happening in fulcro-inspect
. Which has 9632 in the devtools-url
and then 9630 in the CSP rules.
I get this when I open up the chrome console inside of the chrome-panel.
Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
In both background (when clicking the url of extension inspect views) and the chrome panel I get a lot of source map loading errors DevTools failed to load source map: Could not load content for
I now have it running on 9630. I'm not sure why it is different on fulcro-inspect. https://github.com/fulcrologic/fulcro-inspect/blob/3f1e2509c45712c15b7f3a2c64f878e412485286/shadow-cljs.edn#L15 https://github.com/fulcrologic/fulcro-inspect/blob/3f1e2509c4/shells/chrome/manifest.edn#L24
well if you have multiple shadow-cljs instances running locally and 9630 is taken it'll use 9631 then 9632 and so on
:source-map-inline true
worked for chrome-extension
target but doesn't seem to be working for chrome
target https://github.com/homebaseio/datalog-console/blob/extension/shadow-cljs.edn#L21. Though perhaps I have something else configured wrong here?
I also seem to be able to connect to the background
runtime with the repl when I set my devtools-url
to 9630.
When the devtools-url
is set to 9632 I get WebSocket connection to '
followed by shadow-cljs - remote-error
several times before it gives up trying to connect.
I do not understand why you are trying to connect to 9632. shadow-cljs ONLY starts ONE port. there is no such extra magic port with regards to chrome-extension
I was just following the configuration from fulcro-inspect
but it clearly doesn't apply to your setup. it can only connect to a port that actually exists, so don't configure one that doesn't
as for the REPL connection. open http://localhost:9630/runtimes
you can switch to a specific one but the default rule is to connect to the first one that connects
okay. We are doing similar things. Plan to also build an electron app so most of what was done there I thought would apply.
Thanks for pointing out the url for open runtimes. Was a big help. I am able to connect to them with the repl now. Only thing left is source-maps not loading in the panel. But I think this is a path related issue on my end.
inline should fix it but might be a bug in the :chrome-extension
target not supporting it properly or something
yes it fixed it for this one actually.
It was the :browser
target for the panel UI that is still throwing the source map error.
I have a question about an issue I've run into with the :output-feature-set :es5
setting with shadow-cljs.
When my compiled javascript is loaded I get an error that says
Uncaught TypeError: $jscomp.arrayFromIterable is not a function
memoizedFn memoize.js:60
setEnabled history.js:503
<anonymous> events.cljs:458
re_frame$fx$do_fx_after fx.cljc:59
... blah blah ...
<anonymous> babel-polyfill.min.js:1
m babel-polyfill.min.js:1
b babel-polyfill.min.js:1
Using the browser console, I can see that the $jscomp
object is defined, but the function arrayFromIterable
is not defined on it. Other functions are.
I was able to fix this by defining the function in a :prepend
statement for my module.
:prepend "$jscomp.arrayFromIterable = function(a) {return a instanceof Array ? a : $jscomp.arrayFromIterator($jscomp.makeIterator(a));};"
It fixed my problem. My javascript loads but it feels dirty. Is there another way to solve this?normally it just goes away after wiping the cache and recompiling. just try deleting .shadow/builds/<build-id>
I attempted that, but it did not fix my issue
It goes away when I target :es6
but I can't do that because of internet explorer 😞
Not for my enterprise customers unfortunately lol
I will see if I can make a reproduceable small build. That might take me a while to do. I'm working on migrating a really large cljs application to shadow so there are a lot of moving parts. In the mean time, maybe that little hack will help someone.
In testing, what’s a good way to run some js code from a file (`myPreloads.js` ), which mocks some things before running the main test function? Basically, achieving the same thing as copy-pasting the code from myPreloads.js
to the beginning of the test/target/testable.js
file (which obviously isn’t a good idea).
I was able to accomplish this by writing my own preloads and using those in the test build.
If running clojure code won't work for you, you should be able to require the js file in the namespace declaration of your preload file.
Thanks for the reply @dannyfreeman, that seems to do what I want it to! However, now I get a problem with the modules that are required from the preloaded js file. So right now I have my preload namespace:
(ns preloads
(:require ["./myPreloads.js"]))
and the js file I want to run, which requires its own modules
myPreloads.js
...
require("module-alias/register");
...
I get the following error when trying to run the tests:
SHADOW import error /app/.shadow-cljs/builds/test/dev/out/cljs-runtime/myPreloads.js
/app/test/target/testable.js:67
throw e;
^
Module not provided: shadow.js.shim.module$module_alias$register
Looking at the generated testfile testable.js, this is where it does the import.
SHADOW_IMPORT("shadow.js.shim.module$module_alias$register.js");
Can’t really figure out how to require these modules so that shadow can find them. Am I missing something here?That I am unsure about. I did run into some issues around testing code meant for a browser for a node-test target that seems similar. To fix those issues I had to set this option in my :test
profile in shadow-cljs.edn file
:js-options {:entry-keys ["module" "browser" "main"]}
I'm really unsure what the implications of doing that are, but combining that with stubbing out the global window
object got my tests to run in node.
Also, if the contents of myPreloads.js
are pretty simple, you could try re-writing them in clojurescript directly in your preloads
cljs file. Perhaps shadow-cljs doesn't understand the code in your js file.
Okay, from the docs it seems like :js-options
determines which build variant to use for the npm package, e.g. CommonJS or ESM. Unfortunately, adding it doesn’t do anything for me. Unfortunately, myPreloads.js
is quite extensive so I’m trying to avoid rewriting it in cljs.
@thheller any ideas on how to fix this error related to shadow-cljs being unable to import npm modules that are required from a local js-file which in turn was required in a preload namespace? More info in my first reply of this thread
Not sure if it makes a difference, but the modules it can’t find seems to be devDependencies
if your preloads only setup node related things and don't interact with CLJS in any way you can just use node -r ./preloads.js your-test-output.js
there are ways to get it into the build of course but this would be the fastest and easiest
you are much better off using something like https://www.npmjs.com/package/chokidar-cli to watch the test output file and have that rerun the tests when needed
Thanks for the tip, I’ll look into it! Just curious, what’s the reason behind the nested requires not working when using preloads?
it should work but what the code does actually matters and I don't have enough information to say
@dannyfreeman you can do it a little cleaner by setting :compiler-options {:force-library-injection ["es6/util/arrayfromiterator"]}
. the problem is that the polyfill detection logic somewhere makes a mistake and that part gets lost but you can always just tell it which polyfills to include
they are all listed here https://github.com/google/closure-compiler/tree/master/src/com/google/javascript/jscomp/js
so the above would just include https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/js/es6/util/arrayfromiterator.js which you did via the :prepend
well or rather https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/js/es6/util/arrayfromiterable.js
I just tried to use :force-library-injection ["es6/util/arrayfromiterable"]
in my compiler-options and that did not work. arrayfromiterator
also didn't change anything but that function is available already.
Is it possible that arrayfromiterable
needs to be included here: https://github.com/thheller/shadow-cljs/blob/9a4144b65141ecdacc28fefed53fe968035363e5/src/main/shadow/build/closure.clj#L2522
I will try this on a release build real quick
Yeah that :force-library-injection
key works for my release build, but not a development build.
Thank you 🙂 is there anyway I could help out with that?
too late 🙂 should be fixed in 2.12.5. also just added the interable by default so should be ok even without config.
Awesome. I'll be on the lookout for that release. Thank you very much for the help.
Hi, noob question here. What is a common way to set and access env variables, for example to use different firebase configs for dev/prod? I’ve tried using js/process.env but get a ReferenceError: process is not defined. Is there some trick to getting this to work in shadow or cljs in general?
https://shadow-cljs.github.io/docs/UsersGuide.html#closure-defines + https://shadow-cljs.github.io/docs/UsersGuide.html#shadow-env
I’ve configured my env variables and added them to my shadow-cljs.edn as described in those links, but how can I now reference/use them in my cljs code? For example, if I have :closure-defines {app.core/APIKEY #env "APIKEY"}
, I don’t understand how to reach it from within the app.core namespace
If I try something like {:api-key #shadow/env "APIKEY"}
I get a compile error No reader function for tag shadow/env
. And simply referring to it by its name, APIKEY
, I get an undeclared var error
you (goog-define APIKEY "default value")
in app.core
and then use it like any other clojure def