Fork me on GitHub
#shadow-cljs
<
2018-05-18
>
heyarne09:05:51

Can I configure shadow-cljs to write .nrepl-port like figwheel does? That way cider could auto-detect the port

thheller09:05:16

latest version of cider has support for shadow-cljs

thheller09:05:36

shadow-cljs also writes that file when it doesn't exist

heyarne09:05:49

oh cool, good to hear!

thheller10:05:48

@wilkerlucio had an idea how to resolve pretty much all problem and it seems to work very nicely. nothing released yet but I wrote down some stuff here: https://github.com/thheller/shadow-cljs/issues/279

wilkerlucio11:05:38

@thheller interesting, one thing occurred to my mind, if we add new files, that would mean we also have to change the manifest during dev?

thheller11:05:10

"add new files?"

wilkerlucio11:05:20

new cljs files

thheller11:05:05

you only specify :entry. if the entry "reaches" the newly added file it will be automatically added

wilkerlucio11:05:06

so, the files listed there are the goog bootstrap things, + shadow things, + cljs things + 1 single file for the user things, is that correct?

thheller11:05:59

YOU never write the files

wilkerlucio11:05:59

"background":
 {"persistent":false,
  "scripts":
  ["out/background.js", "out/cljs-runtime/goog.debug.error.js",
   "out/cljs-runtime/goog.dom.nodetype.js",
   "out/cljs-runtime/goog.string.string.js",
   "out/cljs-runtime/goog.asserts.asserts.js",
   "out/cljs-runtime/goog.reflect.reflect.js",
   "out/cljs-runtime/goog.math.long.js",
   "out/cljs-runtime/goog.math.integer.js",
   "out/cljs-runtime/goog.object.object.js",
   "out/cljs-runtime/goog.array.array.js",
   "out/cljs-runtime/goog.structs.structs.js",
   "out/cljs-runtime/goog.functions.functions.js",
   "out/cljs-runtime/goog.math.math.js",
   "out/cljs-runtime/goog.iter.iter.js",
   "out/cljs-runtime/goog.structs.map.js",
   "out/cljs-runtime/goog.uri.utils.js",
   "out/cljs-runtime/goog.uri.uri.js",
   "out/cljs-runtime/goog.string.stringbuffer.js",
   "out/cljs-runtime/cljs.core.js",
   "out/cljs-runtime/clojure.string.js",
   "out/cljs-runtime/shadow.cljs.devtools.client.console.js",
   "out/cljs-runtime/shadow.module.shared.append.js",
   "out/cljs-runtime/demo.chrome_bg.js",
   "out/cljs-runtime/shadow.module.background.append.js"]},

thheller11:05:04

that stuff is generated. only stuff in manifest.edn matters. manifest.json is generated.

wilkerlucio11:05:29

yeah, but I'm wondering if when I add a new file, the generated list of scripts will have to change

thheller11:05:35

yes it does

wilkerlucio11:05:57

because I think when you change that, you also have to go into the extensions pages and refresh the extension manually

thheller11:05:59

but you have to reload the extension for any code change anyways

wilkerlucio11:05:07

the manifest is not auto-updated afaik

thheller11:05:19

code isn't either

thheller11:05:39

if you want that you MUST load remotely

thheller11:05:10

but that has several other drawbacks so I opted not to do that by default. but it could be configured to work that way

wilkerlucio11:05:51

not quite, I just tested on the background page here

wilkerlucio11:05:00

the current setup does update

wilkerlucio11:05:06

the content-scripts are the exception I think

thheller11:05:14

which "current setup"?

thheller11:05:23

which old one 🙂

wilkerlucio11:05:27

:chrome-background     {:target     :browser
                                        :output-dir "shells/chrome/js/background"
                                        :asset-path "js/background"
                                        :devtools   {:devtools-url ""}
                                        :modules    {:main {:entries [fulcro.inspect.chrome.background.main]}}}

thheller11:05:45

yeah browser loads remotely

wilkerlucio11:05:42

right now I only refresh the extension when I have to change the content-script, if we go that direction I'm afraid we will have to do more ext refreshes

thheller11:05:10

I'm a bit confused, what exactly are you talking about?

thheller11:05:50

WHICH reload in particular?

thheller11:05:08

the config above is not for a content script

wilkerlucio11:05:24

ok, let me see if I'm also on the same page as you

wilkerlucio11:05:35

I'm talking about the new changes you proposed for the compilation

wilkerlucio11:05:51

in your example, the background page will change from the current browser :target

wilkerlucio11:05:00

and instead will pre-compile and use the files from the manifest directly

wilkerlucio11:05:03

is that correct?

thheller11:05:16

> background page will change from the current browser idea

thheller11:05:21

I don't understand that sentence

wilkerlucio11:05:39

browser target I mean, the way we compile the background

thheller11:05:14

the entire chrome extension is compiled in one build yes. :browser is no longer used.

thheller11:05:31

but that pretty much means nothing in itself

wilkerlucio11:05:40

that I think its a downgrade in the experience for development

wilkerlucio11:05:57

because using :browser, I don't have to refresh the extension when I do updates on the background code

wilkerlucio11:05:17

I just checked

thheller11:05:30

hang on again . .. you are talking about LIVE reload here right?

wilkerlucio11:05:18

about changing code, and refreshing the background page only (open devtools for it from the extensions pane, and use cmd+r in the inspector tool, it refreshes)

thheller11:05:48

hmm you can do that?

thheller11:05:19

hmm I just checked. that works fine?

thheller11:05:32

but yes that could be a problem when new files are added

wilkerlucio11:05:55

I took a tiny screen recording to show it

thheller11:05:07

but it also doesn't trigger the OnInstalled callback

wilkerlucio11:05:04

true, but I think we don't to change that most of the time

thheller11:05:11

sorry I don't get it. it is updating?

wilkerlucio11:05:17

check the log

wilkerlucio11:05:25

after the refresh, the log comes with the new message

wilkerlucio11:05:49

(sorry, I should frozen the last frame more, it transitions back to the gif start quickly)

thheller11:05:55

sorry the gif is a bit fast. can't really tell what I'm looking for?

wilkerlucio11:05:18

I update the bg code, shadow reloads it, you see a new message, then I go into the bg and refresh

wilkerlucio11:05:28

the same file is loaded, now with the updated message on the log

thheller11:05:51

that is also live-reloading so I'm still confused what you are actually talking about

wilkerlucio11:05:06

no, I thin you are missing the refresh on the devtools pane

wilkerlucio11:05:12

when the log is cleared and started over

wilkerlucio11:05:29

check when the elements pane got reset and re-rendered

wilkerlucio11:05:35

that's a refresh

thheller11:05:50

yes I see that

thheller11:05:04

but I do not understand where the problem is?

wilkerlucio11:05:25

there is no problem here, this is the good version, using browesr

wilkerlucio11:05:34

I'm afraid that will be lost with the new proposed changes

thheller11:05:46

WHAT will be lost?

wilkerlucio11:05:49

and instead of a simple refresh on the devtools panel, I'll have to go in the extensions page and ask a refresh there

thheller12:05:08

it works identically AFAICT

thheller12:05:21

I have this

thheller12:05:23

(ns demo.chrome-bg)

(js/console.log "chrome-bg")

thheller12:05:36

:background {:entry demo.chrome-bg}

thheller12:05:46

compile it ONCE and see chrome-bg in the log

thheller12:05:54

I change the log message and compile it ONCE again

thheller12:05:59

CTRL+R to reload

thheller12:05:07

and I see the updated message?

thheller12:05:23

did not do a full reload of the chrome ext

wilkerlucio12:05:44

cool, that's good, I was afraid that would break

wilkerlucio12:05:03

what about new files, had a chance to test that?

thheller12:05:03

why would it though?

wilkerlucio12:05:23

I'm not sure about how chrome caches things there, considering the same scenario doesn't work this way with content-scripts (where I have to go into the ext pane and refresh there every time it changes)

thheller12:05:24

all problems can be fixed but please one problem at a time

thheller12:05:38

content-scripts follow different rules

thheller12:05:52

and it is mostly about HOW the code is loaded and WHEN

thheller12:05:39

the reason it seems to update when using :browser is that the code is loaded async and from remote

thheller12:05:47

so it is not actually loaded from the extension itself

thheller12:05:52

but via http

thheller12:05:05

there are several important aspects to this

thheller12:05:28

nothing in this is specific to :browser. all of this could work identically in :chrome-extension

thheller12:05:37

the point is to figure out what the actual problem is though

thheller12:05:25

async has other issues in particular with :background since you can't use OnInstalled for example

thheller12:05:14

it is totally possible to use async for content scripts but sync for background

wilkerlucio12:05:20

humm, I think I'm getting it now, OnInstalled can only run in the initial code, so async loading for it on :browser is broken, correct?

thheller12:05:23

just trying to identify what you are actually after

thheller12:05:00

half-correct. the :browser loader is semi-smart and detects if it can document.write which means it appears sync

wilkerlucio12:05:00

my idea was just trying to reduce the number of times we have to refresh the ext from the extensions page (or dont increase it, hehe)

thheller12:05:15

yeah but for that we need to when when you actually need to do that

thheller12:05:50

do not think that you are giving up anything when not using :browser. that is not the intention here. keeping all the features but with easier configs is the goal. :browser is too complicated and does too many things we don't need

wilkerlucio12:05:25

gotcha, thanks for the clarification 🙂

thheller12:05:13

if you see a reproducible thing that doesn't work as expected let me know

thheller12:05:25

this is far from done yet but I do think the direction is good

thheller12:05:48

so far I haven't come up with a reason not to this

thheller12:05:59

meaning putting everything into one build driven by the manifest.edn vs. having multiple separate builds

thheller12:05:55

how the code is loaded is completely costumizable

thheller12:05:48

so the most important question currently would be to decide if there is a reason NOT to combine everything into one build. in which scenario would that NOT work.

wilkerlucio12:05:34

I think currently the major pain point you described already, that's how to switch the REPL target

thheller12:05:54

I think :content-scripts can always load async remotely. they don't have any special lifecycle callbacks anyways right? eg. no OnInstalled

wilkerlucio12:05:11

humm, there is a catch there

wilkerlucio12:05:53

I might want to inject things on page DOM via content-script before the user code is there, (like settings a flag so the user know an extension is installed)

wilkerlucio12:05:59

if the code loads async, that will break I think

thheller12:05:20

yeah if you need document_start then that breaks

wilkerlucio12:05:20

so, problem only for document_start

thheller12:05:32

but since that is part of the config

thheller12:05:42

the compiler could emit the correct thing

👍 4
thheller12:05:29

still need to figure out how to do the programmtic content script inject

wilkerlucio12:05:37

one idea, what you think on using namespaced keywords for shadow things? like :shadow/entry?

thheller12:05:40

declarative is easier

wilkerlucio12:05:59

so we can avoid collisions with regular manifest things

thheller12:05:19

probably a good idea. easier to filter out later.

thheller12:05:52

but currently its just :entry not sure what else we need

thheller12:05:02

thats easy enough to filter

wilkerlucio12:05:22

yeah, just trying to be future proof

wilkerlucio12:05:42

we never know if chrome might decide they want to use entry key for anything

thheller12:05:17

true. its also more visible/obvious in the config.

thheller15:05:15

@wilkerlucio (js/chrome.runtime.reload) actually does a full reload of the extension. could bind that to a key in cursive.

thheller15:05:53

could also do it :dev/before-load but it loses all state so not super great

lilactown17:05:48

excluding the closure compiler from clojurescript & adding in the version you specified fixed it 👍

lilactown17:05:53

thank you thheller!

theeternalpulse20:05:11

So is figwheel needed when using the shadow-cljs dev tools? It pretty much live-reloads and exposes the nrepl server, so is figwheel needed for some other cases?

thheller20:05:58

figwheel is never needed no. its not supported in fact.

theeternalpulse20:05:24

ok cool. Also yesterday you gave me a startup app that instructed to use npx server and watch app seperately, but shadow-cljs watch app does both in one command. Other than having the ability to stop one or the other, is it advised to use the shadow-cljs command over npx?

thheller20:05:04

npx is only useful in case you do not have shadow-cljs installed globally. if you do you can skip npx.

thheller20:05:28

running the server instance separately however is recommended but not required

thheller20:05:13

it becomes more useful when you start using REPLs and multiple builds. just using watch is fine if you only have one build

theeternalpulse20:05:25

great, loving it so far, still have yet to catch your interview on defn podcast

wilkerlucio23:05:57

congrats man 🙂

wilkerlucio23:05:55

how we can package libraries for things developed with Shadow? had anybody ever done that? how to share the npm dependencies? stil using lein for generating the jar?

thheller23:05:18

yeah I still haven't worked on that. pretty complicated topic. lein works fine so I recommend that.

thheller23:05:43

npm deps you can put into a deps.cljs at the root of you lib via {:npm-deps {"react" "some-version"}}

thheller23:05:11

shadow-cljs will isntall those on server start of shadow-cljs npm-deps

thheller23:05:06

but given the state of :npm-deps support in CLJS that might not work too well outside shadow-cljs

thheller23:05:59

no clue how it works together with cljsjs

wilkerlucio23:05:51

for my case I'm ok been shadow only

wilkerlucio23:05:38

but there is not much now, I think if we want to actually use the npm ecosystem, shadow is the only way until cljs core / closure figures on that side

wilkerlucio23:05:21

do you know if there is a tool to read from package.json and spit on deps.edn?

thheller23:05:53

doubt that deps.edn is going to support npm anytime soon

wilkerlucio23:05:23

well, so shadow is the way to go 🙂

wilkerlucio23:05:58

one thing just occured to me about the manifest.edn, did you though about how to add extra compilations there? (besides content-script and background)

wilkerlucio23:05:16

another common cases are js for popup pages, devtools, apps...

thheller23:05:30

yes. just extra things in the config.

wilkerlucio23:05:30

and those don't have a place in the regular manifest, they are loaded via html

wilkerlucio23:05:09

you already have an idea of what that will look like?

thheller23:05:35

:page-action {:shadow/entry foo.bar :shadow/output-to "page_action.js"}

👍 4
thheller23:05:29

so you could write the popup.html and just <script src="page_action.js">

wilkerlucio23:05:46

ok, but that should be under some other key right? to avoid collision with regular manifest keys

thheller23:05:36

yeah. not yet sure what makes the most sense

wilkerlucio23:05:10

namespaces are another option, but I feel like the nesting might be less confusing

thheller23:05:42

yeah I'm currently trying to address the multiple REPLs issue

thheller23:05:53

haven't thought more about the compilation stuff

thheller23:05:36

if you have something that you'd like to see I'm open to adding it

wilkerlucio23:05:50

ok, I'll stop breaking your focus 🙂 I'll try to think on those too and I'll let you know if get some idea

thheller23:05:18

this is a pretty big issue that ideally should have tool support

thheller23:05:27

but thats probably going to take a while 😉

wilkerlucio23:05:38

is that shadow retuning status code 130 on ctrl+c expected?

thheller23:05:06

that seems to be a npm v6 thing

wilkerlucio23:05:17

cli version: 2.3.23 node: v8.11.2

wilkerlucio23:05:30

are you using the 10?

thheller23:05:47

which npm -v?