Fork me on GitHub
#shadow-cljs
<
2021-02-03
>
thheller00:02:14

@jaime.sangcap see the link above. seems to be picking the wrong IP too

jaime20:02:35

When I run react-native log-android in different terminal, it logs almost the same thing as the bundler (in again another terminal where I run react-native start) . No log about IP address. Am I missing something? How to I know what is the IP of the emulator?

thheller21:02:36

you don't need to know the IP of the emulator. you need to know the IP of the machine shadow-cljs is running on.

thheller21:02:31

and that IP needs to be reachable by the emulator. dunno how to find that info either. I don't do react-native dev

jaime21:02:53

Oh ok got it. Thank you for the info.

alexdavis16:02:03

hey I’m getting

[2021-02-03 16:09:28.301 - INFO] :shadow.build.npm/js-invalid-requires - {:resource-name "node_modules/@aws-amplify/ui-components/dist/cjs/index-e94df828.js", :requires [{:line 1632, :column 73}]}
Trying to use https://www.npmjs.com/package/@aws-amplify/ui-react lib and requiring it like
(:require ["@aws-amplify/ui-react" :refer [AmplifyAuthenticator AmplifySignOut]]...
I think the problem is here but not entirely sure what I can do about it
return Promise.resolve().then(function () {
    return _interopNamespace(require(`./${bundleId}.entry.js${ ''}`)); }).then(importedModule => {...}, consoleError);
Any ideas?

thheller16:02:56

no luck. that pattern is not supported. it is webpack specific. if you must use that lib you can follow option 2 https://code.thheller.com/blog/shadow-cljs/2020/05/08/how-about-webpack-now.html

alexdavis16:02:37

Makes sense, thanks a lot! Maybe it’s not that easy but if you linked to that article or even put the error you get into the article so it comes up when someone Google’s it that might save you some time answering silly questions like this

alexdavis16:02:25

But it’s been a while since I switched to shadow and this is the first speedbump I’ve ran into which is a vast improvement on other tools so thanks in general!

thheller16:02:32

yeah it is rare but some libs expect you to use webpack and really aren't happy with anything else

Adam Helins21:02:11

Is there somewhere a rough description of how the watch algorithm decides what to recompile and what to read from the cache? At first I thought that it was systematically recompiling any child namespace (makes sense). But it isn't always true around the entry namespace of a module from what I see with --verbose and it puzzles me.

thheller21:02:14

the namespace you changed and all namespaces that directly require it by default

thheller21:02:26

also all namespaces with warnings since they are never cached

thheller21:02:19

and all namespaces marked with :dev/always and all namespaces blocked for caching by :cache-blockers

Adam Helins21:02:36

So the entry namespace of my main and only module should always recompile? Because all I see is:

-> Flush: meloview/comp/root.cljs
<- Flush: meloview/comp/root.cljs (5 ms)
No Compile CLJS or Cache write for that namespace

Adam Helins22:02:43

Oh, when you say "directly", do you imply that in A requires B which requires C, A might not recompile when C changes but B always will?

thheller22:02:30

yes. the logic is that if you change C (eg. remove a def, add a def, change defn signature, etc) then B should be recompiled because it may now have warnings/errors but A cannot

Adam Helins22:02:44

Great, that explains it all. I was under the false assumption the whole tree would recompile. Many thanks!

thheller22:02:18

no, that gets rather slow in larger projects and isn't usually required.

witek22:02:46

Hallo. I am looking for an idea how to get a string which is generated in the browser into a specific file in my project directory. My usecase: My code is pure cljs, not cljc. I have a kind of model driven application. So inside the browser I can collect information about it's internals and generate documentation metadata. I want this documentation data into a file, as soon as compilation completes and a callback hook in the browser is called. Since shadow-cljs which runs on the filesystem already communicates with the browser, I thougt there might by a way to do the trick. Any suggestions?

thheller22:02:39

I don't understand. you need some kind of server you POST the data to or so

witek22:02:00

Having something like (shadow-cljs.browser-tools/write-file "target/info.txt" "file content here") would be optimal.

thheller22:02:55

shadow-cljs does not handle server code for you. you'll have to write that.

witek22:02:36

No, I need this thing to only work during development. When a shadow-cljs hook is called in the browser. I would like to be able to call some magic function from shadow-cljs which sends the data back to the shadow-cljs server which writes it to a file.

thheller22:02:10

I repeat. no shadow-cljs does not handle such a case for you. you do have to write it yourself.

thheller22:02:24

you may use a custom http handler from the :dev-http server

witek22:02:45

How does a test reporting tool do this? When the tests run in the browser, how do the results get to a file on the server? Or don't they?

thheller22:02:02

they don't. at least in shadow-cljs :browser-test

witek22:02:23

@thheller thank you anyway!

thheller22:02:59

@witek it may not be obvious but what you are asking is about 5 lines of code with a custom :handler. so I do not see the point in shadow-cljs providing such a thing.

witek22:02:31

I have no server in my project. It's pure JavaScript for Google Firebase.

thheller22:02:28

but you have shadow-cljs running and use :dev-http? https://shadow-cljs.github.io/docs/UsersGuide.html#dev-http

witek22:02:02

You are right, thank you! I tinkered with macros for a half day. :man-facepalming:

thheller22:02:05

@witek set :dev-http {3000 {:root "public" :handler my.handler/handle}} and

(ns my.handler
  (:require [shadow.http.push-state :as push-state]
            [ :as io]))

(defn handle [{:keys [uri] :as req}]
  (if (not= uri "/save-me")
    (push-state/handle req)
    (do (spit (io/file "somewhere" "foo.txt") (slurp (:body req)))
        {:status 201
         :body ""})))

thheller22:02:28

then from the browser side just send a post request to /save-me

thheller22:02:58

or something like that. didn't test the above but should be ok.

👍 3
Elis Popescu22:02:13

Hi! Is there a way to add in my shadow-cljs.edn a "build step" to execute an external command every time I run the build? For example to run postcss input.css -o out/out.css`` . Ideally with a watch function, so it runs that command only when the input.css changes?

thheller22:02:44

@elisescu see :build-hooks in the docs. fair warning though this is almost always a bad idea since it will slow down you CLJS recompile cycle

Elis Popescu22:02:29

Got it. Any suggestion of how to do something like that better? Or I should leave it completely out of the shadowcljs build process? And thanks a lot for the very quick reply.

thheller22:02:30

I just run things like that separately. sometimes with something like https://www.npmjs.com/package/foreman or alternatives

johannjohann22:02:37

howdy all--i recently have been playing around with using shadow cljs to emit ecmascript modules (esm) for denojs--i'm not sure if this is a newish thing, but since deno defines a global window object, a particular line of code in the shadow.dom package is causing an error

johannjohann22:02:11

i.e. the code defining shadow.dom/transition-supported? which looks like

shadow.dom.transition_supported_QMARK_ = (((typeof window !== 'undefined'))?goog.style.transition.isSupported():null);
so i am wondering if theres a way to prescribe to shadowcljs to not include some of these helper packages? help much appreciated!

thheller23:02:16

you probably forgot to configure :runtime in the build config. that defaults to browser. for :deno you'll need :runtime :custom since I have not implemented hot-reload for it at all.

thheller23:02:14

as mentioned here https://clojureverse.org/t/generating-es-modules-browser-deno/6116 only compile and release kinda work for now.

johannjohann23:02:04

huzzah! thank you friend 🙂