Fork me on GitHub
#shadow-cljs
<
2018-01-10
>
cmal04:01:02

Hi, I am trying to add d3 as a deps in a shadow-cljs project. I've found that in shadow-cljs demo/browser.cljs, it uses (:require ["d3" :as d3]) to include d3 but the "d3" in shadow-cljs.edn was commented out. I am wondering how the d3 in demo/browser.cljs can work. Should I add d3 in the package.json and (:require ["d3" :as d3]) to make d3 work in my project?

cmal05:01:37

I add d3 to package.json and (:require ["d3" :as d3]), it works!

Alex H06:01:08

@thheller I'm guessing you are aware, but I've just seen that clojurescript's :foreign-libs thing does seem to have support for the kind of preprocess step we were talking about yesterday: https://clojurescript.org/guides/javascript-modules#babel-transforms. I don't think that changes anything w.r.t. shadow-cljs, but might offer some inspiration

thheller08:01:54

@alex340 yes I’m aware. I suggested the :preprocess a.qualified/symbol syntax. so far I have gotten away without any configuration for this and babel in theory could automatically be applied if there was a .babelrc present

thheller08:01:21

@cmal you might want to consider using the separate d3-* packages instead of the d3 meta package. eg. (:require ["d3-color" :as d3-color]) instead of accessing the d3.color property. avoids always importing everything.

cmal08:01:30

OK. Thank you @thheller

cmal08:01:02

@thheller Does the "d3-color" here means I should add a d3-color to my package.json in the same directory of shadow-cljs.edn?

thheller08:01:32

if you add just d3 they will all be there already

thheller08:01:56

but you can also skip the d3 install there and just install what you need in package.json

hlolli10:01:55

@thheller :shadow.build/mode showed to me :dev despite useing whitespace optimization. As for background scripts, it takes an array so I see it as one way to serve the depending js files, maybe there's another way to do it, but for example adblockplus uses 7 js files in background scripts. If it's only for development then it's probably ok, the user needs to http regex match if they want it to run on all or only specific addresses.

thheller10:01:44

:optimizations only apply for shadow-cljs release. they are ignored otherwise.

hlolli10:01:31

ok, so my test is really, is this a single file output compilation or does the cljs-runtime dir get bundled too.

thheller10:01:36

it could just always emit a single file

hlolli10:01:55

hmm like the karma example?

thheller10:01:37

I don’t know if background scripts are allowed to importScripts or something to load other files

thheller10:01:31

why did you mess with :module-hash-names in the example? that doesn’t seem useful for chrome exts? the hash names are meant to that you can http cache the files forever since new versions will have different names

thheller10:01:58

didn’t have time to look into the chrome exts stuff yet so I don’t know any details

thheller10:01:13

does the REPL/hot reload work? is the ext allowed to connect to localhost?

hlolli10:01:37

hmm, that was not willingly 🙂

hlolli10:01:25

good question, I never found documentation so far that it's part of js dev practices. Reloading an extension is either a button or you can dowload an extension to reload all extensions.

thheller10:01:55

if the extension is allowed to connect to the websocket the CLJS hot reload should just work

thheller10:01:10

but not sure the security model allows that

hlolli10:01:15

ok, so I will give it a try

thheller10:01:02

for now you can re-use the “generate single file” from the karma stuff

thheller10:01:21

might move that into the output ns at some point

thheller10:01:33

I had a :compact mode at some point which did basically that

thheller10:01:18

single file wasn’t great for http development but might be perfect for chrome exts

hlolli10:01:40

that could be!

hlolli10:01:25

@thheller https://gist.github.com/hlolli/265b9183566a4c5829d7ee355e3d0998#file-chrome_extension-clj-L63-L64 isn't this how :module-hash-names should be, don't think you copied all the code above 🙂 ?

thheller10:01:56

why do you want hash names?

hlolli10:01:15

ah you ment the oppisite, not useful haha ok

thheller10:01:19

it is an optimization for HTTP. you are not serving over http and thus not useful

hlolli10:01:40

ah ok, I thought it was for hasheing for recompilation.

thheller10:01:51

nah that is solved elsewhere

hlolli10:01:58

is inject-loader-setup-release useful?

hlolli10:01:41

ok, I see that for flush, like your point was above, to only flush the crx-manifest

hlolli10:01:39

signal I need to make coffee

thheller10:01:23

I’m not sold on actually generating the chrome manifest via the build

thheller10:01:38

you can write it by hand and if you only generate one file you don’t need to modify the manifest at all

hlolli10:01:19

@thheller yes that's right, the only reason I wanted to generate it was because I didn't want to type in all the files. If it's one file, then there's no reason to generate it.

hlolli10:01:26

don't I lose some optimization of haveing it in one file, say I only change one namespace, then all the data is compiled?

thheller10:01:06

so from the build perspective the flush is the last step

thheller10:01:11

it does not affect compilation

thheller10:01:24

so all caching and stuff remains the same

hlolli10:01:41

ah I see, nice

thheller10:01:43

flush only takes the compiled resources and writes it to disk in whatever format

thheller10:01:58

if you write 100 files or one doesn’t matter (much)

thheller10:01:59

flush also always happens by default for safety

thheller10:01:10

so even if nothing was recompiled the flush may still happen

thheller10:01:33

by default there are some checks in place to avoid some IO but technically you could just always write

hlolli11:01:22

ok, this sounds very boot-ish

eveko11:01:56

How would one setup the on reload function for a reagent app?

thheller11:01:00

do you mean the reagent side of things or the shadow-cljs config for that?

eveko11:01:45

I can get the on-reload function that i designated to fire

eveko11:01:09

but just calling my applications start function is returning an error

eveko11:01:23

so in the end I have to reload browser to see changes

thheller11:01:37

what kind of error?

thheller11:01:32

usually you should just need to render again

thheller11:01:55

you can also use the :before-load to unmount and then mount :after-load

thheller11:01:56

init once, then repeated start -> stop -> start -> ... for each hot reload

eveko11:01:51

these are my two functions

eveko11:01:31

when reload gets callled

eveko11:01:19

on the console in browser I get error rendering component

thheller11:01:37

looks ok to me. what is the error?

eveko11:01:31

Error: No method in multimethod 'dashboard.routing/current-page' for dispatch value:

eveko11:01:23

and if I just call begin on :after-load

eveko11:01:28

Error: Target container is not a DOM element.

thheller11:01:54

try logging the value of (js/document.getElementById "app")

thheller11:01:03

seems like that gets removed from the page somewhere

thheller11:01:13

FWIW (defonce app-container (js/document.getElementById "app")) and then (r/render [..] app-container) is probably the safer thing to do

eveko12:01:09

now I always get Error: Target container is not a DOM element.

thheller12:01:06

and what is (js/document.getElementById "app")?

thheller12:01:21

I assume you have a <div id="app"> in your html?

eveko12:01:07

yeah it is in there

eveko12:01:12

I got rid of the errors

eveko12:01:23

but now I just reloads and the page stays blank

eveko12:01:05

but I think I know what the issue is

eveko12:01:40

I get the html from a server response

eveko12:01:56

not by serving the static file

eveko12:01:12

so when I call the reload there is just nothing 😕

eveko12:01:07

no statically serving the file did not help either. Now I get no error but the page is blank...

thheller12:01:26

I’m confused.

eveko12:01:07

It renders fine if reload the page manually

eveko12:01:58

but the after load function just removes everything.

thheller12:01:48

so something is clearing your DOM,it is definitely not shadow-cljs doing that

thheller12:01:03

maybe (route/app-routes)?

thheller12:01:16

or the namespace that was reloaded?

eveko12:01:52

had to make te route state into a defonce

eveko12:01:55

now it works

hlolli13:01:59

I've updated the script https://gist.github.com/hlolli/265b9183566a4c5829d7ee355e3d0998 runs smoothly, works well when output-dir is set to target and the output-to single file to the directory I'm working on

:output-dir "target/js"
:output-to "js/main.js"
Tried adding the autoreload :devtools {:autoload true} and starting the repl shadow-cljs cljs-repl :my-id opening the extension background page I get
main.js:90082 WebSocket connection to '' failed: Error in connection establishment: net::ERR_NAME_NOT_RESOLVED
DEVTOOLS: disconnected!
must be my config, read that websockets are fine in crx's.

thheller16:01:59

@hlolli by default it uses js/document.location.hostname to connect to which is incorrect here

thheller16:01:40

try setting :devtools {:use-document-host false}

colindresj22:01:11

@thheller if I remember correctly shadow already includes https://github.com/binaryage/cljs-devtools, but I’m not seeing formatted logging. Is my memory wrong?

thheller22:01:04

no it doesn’t include cljs-devtools but it does have its own little console utilities which do basic formatting

thheller22:01:13

not as colorful though

thheller22:01:33

should still be able to expand any clojure collection and see it properly

colindresj22:01:21

Oh ok, nvm then. I’ll just add it separately

thheller22:01:20

yeah just add it to the classpath and :devtools {:preloads [devtools.preload]} … way too much devtools in that line but it works 😉

thheller22:01:45

I could add it automatically whenever it finds cljs-devtools on the classpath

thheller22:01:50

might make that easier

colindresj22:01:55

Yeah that’d be pretty cool

thheller22:01:00

yeah let me do that

colindresj22:01:04

I almost never continue a project without it

thheller22:01:53

[email protected] should automatically include it if its on the classpath

thheller12:01:57

thanks! @U0CKQ19AQ started writing a user guide yesterday. I like that format a lot more than the wiki so I’ll be moving all documentation over to that. See https://shadow-cljs.github.io/docs/UsersGuide.html

thheller12:01:42

PRs very welcome. I’ll work on this primarily for a while until I’m not ashamed of the docs anymore 😉

mhuebert12:01:34

i’ve added a link to the user guide in the wiki home

thheller12:01:55

its still in pretty rough shape so it might not be that helpful yet

colindresj16:01:14

Added a quick PR to document this update

tony.kay17:01:25

Might want to hold off on PRs for a few days. I work pretty rapidly on docs, and it would be distracting and confusing. I'd more appreciate additions to the wiki with issues opened on the repo pointing to that content. That way I can pull it in when it makes sense.

tony.kay17:01:50

unless it is just typo/clarification stuff...those can be fine. But I may re-org pretty dramatically this early

colindresj18:01:02

Yep, no problem. Feel free to merge or cancel if it feels like too big a change.