Fork me on GitHub
#boot
<
2015-09-26
>
kardan07:09:37

I’m trying to get boot-cljs to work by following the steps in the readme but so far no luck https://gist.github.com/kardan/41f9d5a7388368792330. Any hints on what I’m doing wrong?

michal09:09:58

i tried recently to give clj-refactor a try but looks like it’s closely tied with leiningen and its project.clj. function cljr-add-project-dependency for example does not work at all. I tried to ask maintainers for a help but seems that this is boot architecture which makes it hard to reuse with clj-refactor. could you take a look at https://github.com/clojure-emacs/clj-refactor.el/issues/238 and briefly enlighten me what’s the story behind classpath- vs realpath-based file locations?

martinklepsch09:09:29

@kardan: you need to add clojurescript as a dependency

lukemorton10:09:18

Getting this sometimes with boot-cljs and boot-reload: Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

martinklepsch11:09:38

@lukemorton: can you paste the full stacktrace? (or a screenshot of it)

lukemorton11:09:07

Just referenced my browser will do next time it occurs

martinklepsch11:09:39

hm, so there’s no actual stacktrace

martinklepsch11:09:08

@lukemorton: what files are being reloaded?

kardan11:09:41

@martinklepsch: ha, missed that 😇 thanks

martinklepsch11:09:00

@kardan: no problem! if you’re starting a new cljs project you might also want to checkout tenzing: https://github.com/martinklepsch/tenzing

lukemorton11:09:53

tenzing is awesome simple_smile stripped it down a little but the thing Im working on is based on it

kardan11:09:57

cool, will have a look. I’m just started with the client side of things & have not really used cljs much

martinklepsch11:09:01

@lukemorton: what did you strip away?

lukemorton11:09:52

Simplified the build.boot tasks to my needs

martinklepsch11:09:58

@lukemorton: re your issue I’d check the reloaded files for documentWrite calls and trace that to your code

lukemorton11:09:31

also I haven't kept the boot.properties file, not sure the need for it

lukemorton11:09:50

and I haven't got src/cljs, just src/my_namespace

martinklepsch11:09:55

@lukemorton: it’s to pin boot version and specify a clojure version to use

martinklepsch11:09:09

you don’t always need it but it’s “safer"

lukemorton11:09:38

will add back, oh and I put sass in resources

martinklepsch11:09:09

@lukemorton: why? if you put it in resources it will be part of the build?

lukemorton11:09:32

ah thats why I see Compiling sass/app.scss Compiling app.scss

lukemorton11:09:19

what does "resources" mean? I figured it was assets like .sass and .html

martinklepsch11:09:26

yes, but .sass isn’t yet a “resource” because you compile it to css first, then this css file could be considered a “resource"

lukemorton11:09:41

Coming to clojurescript new, the messy chestnut project.clj and weird env/dev/ files was just a bit much. Found boot and tenzing easier to work with especially given a small bit of experience with gulp and ring

lukemorton12:09:02

@mathiasx: boot-sassc doesn't compile when an @import'd file changes, is this expected?

martinklepsch12:09:30

@lukemorton: does the imported file start with an _?

juhoteperi12:09:56

@martinklepsch: Boot-sass should now support .sass files

martinklepsch12:09:37

@lukemorton: try with a prepended underscore, I think sass has some rule about imported things needing to start with an underscore

lukemorton12:09:21

You were right about the underscore! Too used to sprockets

martinklepsch12:09:36

@juhoteperi: cool. Just tried and failed because the sass4clj dep is outdated I guess.

juhoteperi12:09:55

Ah forgot to deploy that one parhaps

juhoteperi12:09:00

should be deployed now

martinklepsch12:09:50

how do I updated an already downloaded snapshot?

juhoteperi12:09:15

umh, one way would be to remove it from m2

juhoteperi12:09:40

Maven will sometimes chek for new versions

martinklepsch12:09:56

boot show -U just worked for me

micha14:09:35

@onetom: that's amazing

juhoteperi16:09:34

Aargh, ws-host pr broke it

juhoteperi16:09:32

@martinklepsch: Have you looked into boot-cljs exception handling?

martinklepsch17:09:05

@juhoteperi: nope

juhoteperi17:09:59

I'll look into it

juhoteperi17:09:04

Oh right.... if we rethrow the errors we have no way to pass the message forward like we currently do

martinklepsch17:09:30

oh. that makes sense.

juhoteperi17:09:12

Looks like it's best to rethrow all exceptions from boot-cljs and handle them in boot-reload

martinklepsch17:09:47

and then rethrow them again for other tasks?

juhoteperi17:09:16

And the exceptions from cljs compiler are wrapped in ExecutionException when boot-reload sees them

juhoteperi18:09:38

Very strange. Boot will print the correct exception data but I can't seem to access that from boot-reload.

juhoteperi18:09:13

Now I see it

juhoteperi18:09:37

The data is only on concurrent.ExcecutionException message 😞

juhoteperi18:09:39

I wonder if that's from parallel stuff in boot-cljs or from pods

juhoteperi18:09:12

@micha: How do exceptions work with pods?

micha18:09:44

what's up?

juhoteperi18:09:55

I'm trying to handle boot-cljs exceptions in boot-reload

juhoteperi18:09:18

But the exceptions lose the ex-data somewhere

micha18:09:45

how can you handle them in boot-reload?

micha18:09:16

oh reload will catch the exception?

micha18:09:08

and the ex-data doesn't make it across the pod boundary?

micha18:09:37

hm let me do a test here

juhoteperi18:09:59

If I understand pods, everything goes to pods through pr-str and comes out through read-string

juhoteperi18:09:17

But I don't see how that would work at all for exceptions

micha18:09:12

yeah exceptions don't go through the pr-str branch

juhoteperi18:09:56

One solution would be to catch all exceptions in boot-cljs impl, return data and then throw new exceptions in boot-cljs

micha18:09:36

i smell a coconut somewhere

micha18:09:03

the ex-data issue is due to clojure objects not being resolvable in other clojure runtimes

martinklepsch18:09:10

could this be handled more easily if we’d not use pr-str for passing things between pods?

micha18:09:18

this would be something boot could handle in the pod interface perhaps

micha18:09:37

boot would need to catch exceptions in the eval code in the pod

micha18:09:49

and rethrow them with the data encoded in a string or something

martinklepsch18:09:49

passing tmpfiles is also something that feels like it should work

micha18:09:07

it's not the pr-str in this case, with the exceptions

micha18:09:18

because it never goes through that branch of the code

micha18:09:51

the relevant part of code

micha18:09:27

i think what we'd have to do is create an exception class in java in the boot java code

micha18:09:46

with a data property (string)

juhoteperi18:09:58

I don't see how you could support all exceptions classes

micha18:09:08

you can't, for sure

kardan18:09:10

Taking first steps with cljs, and are stumbling a bit. If I don’t use “serve” to run my app. How do I "get to” the target/main.js file? Anyway to pipe things to a dir like resources/public/js ? Or is it time to learn the classpath properly 🙀

micha18:09:23

but you could support ex-info, which is pretty key

micha18:09:01

@kardan: what do you mean by "get to"? like what are you wanting to do exactly?

micha18:09:07

@juhoteperi: the fileset seems to be the best place for the error stuff, perhaps

juhoteperi18:09:47

@micha: The first idea was to catch exceptions in boot-cljs side and have boot-reload read them from fileset

juhoteperi18:09:07

but e.g. speak is waiting to catch exceptions

martinklepsch18:09:10

@micha @juhoteperi is there no way to serialize exceptions in java?

martinklepsch18:09:33

couldn’t pods just catch all exceptions and “send them back” ?

micha18:09:35

yeah boot-reload would have to catch the exception and rethrow

micha18:09:57

i was thinking boot-cljs would still throw

micha18:09:11

but it would also add a file to the fileset with data about what went wrong

juhoteperi18:09:02

Hmmh right, boot-cljs could write to the file inside pod

kardan18:09:11

@micha I’m just trying to compile cljs and host it in my clojure web app simple_smile But I think I confuse myself

micha18:09:15

adding the info to the file itself though might be the best way, via tmpfile metadata

micha18:09:29

that way boot-reload would know if the error is relevant or not

juhoteperi18:09:33

@micha: tmpfile metadata would need to be set outside the pod

juhoteperi18:09:42

and I can't access the exception data outside the pod, even in boot-cljs

micha18:09:43

yeah the same as the dependency ordering

micha19:09:02

it would have to be returned from the cljs impl

micha19:09:07

just like the deps

juhoteperi19:09:15

But then it's the same just to throw it

juhoteperi19:09:56

To return anything from impl, I have to catch all exceptions

micha19:09:59

@kardan: what kind of clojure web app? are you using ring, for example?

kardan19:09:30

@misha: yes, http-kit, bidi with ring

micha19:09:06

ok so with ring you can just use wrap-resource, wrap-content-type etc

micha19:09:18

you don't want to be looking in the target dir really

micha19:09:33

boot will set you up with all the things as resources on the classpath

micha19:09:45

wrap-resource serves from the classpath

micha19:09:11

the classpath is the core of JVM programming, so i recommend getting a basic understanding of it

micha19:09:08

the problem the classpath solves is how to access parts of the program that aren't in memory

kardan19:09:09

ok, think I know what I need to do (beside reading up on the classpath..)

micha19:09:58

like applications, if they're at all complex, will have parts of them in files on disk, in compressed archives, etc

micha19:09:10

like in clojure we want to use maven dependencies

micha19:09:44

or you may have a web server program (like http-kit, ring, etc) that will be serving resources

micha19:09:12

the classpath is an abstract interface on top of the "resources" the JVM has access to

micha19:09:48

so for example when you do (require 'foo.bar) in clojure, clojure knows it needs to look for a resource named foo/bar.clj

kardan19:09:49

I always just thought of it as the path in the terminal (but that might be to simplistic)

micha19:09:02

it's sort of like the path in plan9 perhaps

micha19:09:08

like in plan9 everything is a file

micha19:09:12

and has a path

micha19:09:18

like the /proc filesystem

micha19:09:46

like in unix you can haev a fifo or unix domain socket

micha19:09:54

but you access it as if it were a file

micha19:09:07

the classpath is doing a similar thing

kardan19:09:07

ok, thanks for the explanation. Think I have to play around a bit to get things clear

juhoteperi19:09:49

Hah, I think I found way to even get original stacktraces from cljs exceptions

juhoteperi19:09:59

by manually serializing and deserializing them

juhoteperi19:09:25

It keeps the original stacktrace and cause stack

micha19:09:48

what does it serialize it to?

micha19:09:54

ah right, so you can return that from the pod

juhoteperi19:09:49

ex-data could have something which can't be printed 😕

micha20:09:38

putting unprintable things in an exception would be strange

juhoteperi20:09:56

well unreadablöe

micha20:09:09

yeah like a closure or something

juhoteperi20:09:25

cljs compiler puts file objects to ex-info sometimes

juhoteperi20:09:05

or well, pretty much always

micha20:09:11

yeah i think that's odd

juhoteperi20:09:25

Luckily it's probably only thing that causes problems

micha20:09:18

file objects can be serialized i think

juhoteperi20:09:37

I just walk the ex-data and convert Files to strings

micha20:09:55

perhaps we should use the java serialization stuff instead of clj reader/printer

micha20:09:00

i mean for boot in general

juhoteperi20:09:57

I wonder if tasks should have a way to mark exceptions so that boot won't print stack trace for them?

juhoteperi20:09:11

Then boot-cljs could display simple warnings itself and rethrow exceptions for other tasks

juhoteperi20:09:27

But user has no need to see the horribly long stacktrace

micha20:09:14

you could just convert exceptions to warnings in boot-cljs perhaps

juhoteperi20:09:35

I think they should still be exceptions

juhoteperi20:09:20

Other tasks can't go forward if exception happened during cljs compilation

micha20:09:34

yeah you can just not call the next task, no?

micha20:09:53

is it possible to make an exception that has no stack trace?

micha20:09:38

so that would achieve the objective, no?

juhoteperi20:09:40

"Stack trace of root exception is empty; this is likely due to a JVM optimization that can be disabled with -XX:-OmitStackTraceInFastThrow." 😄

juhoteperi20:09:35

Also, it will still print ex-data because I need that for boot-reload

juhoteperi21:09:17

Perhaps I'll provide another task with boot-cljs which can be used as last part of pipeline

micha21:09:10

what about using the java logging facilities

micha21:09:32

maybe if boot used a logger you could control how stack traces are printed etc

juhoteperi21:09:07

Do java loggers allow that?

juhoteperi21:09:25

I have only seen option to either print or not print the stack trace

juhoteperi21:09:44

And not per logger class?

micha21:09:11

i'm not sure

micha21:09:23

it seems like something logging would deal with maybe

juhoteperi21:09:12

Perhaps it'd be possible to write custom Layout class which checks message logger and logs stack trace based on that...

juhoteperi21:09:21

But doubt that would be best solution

juhoteperi21:09:07

For now, I think I'll just let it print full execptions on console

juhoteperi21:09:13

With minor polishing, e.g. I can catch all ExecutionException and rethrow their causes to remove one layer of cause stack

juhoteperi21:09:05

I think I finally found quite good and simple solution

juhoteperi21:09:00

Boot-cljs will "modify" existing Cljs exception instead of wrapping it in another exception-info. Mostly it will replace file-path which points to temp-dir with one that points to original source-path.

juhoteperi21:09:23

And boot-reload will show all exceptions, cljs exceptions just happen to have line number etc. on ex-data.

micha22:09:47

awesome yes

juhoteperi22:09:02

Did you already check the boot-cljs code? 😄

juhoteperi22:09:26

Mostly the added code is for serializing and deserializing exceptions (and tests for it)

juhoteperi22:09:48

Other than that, the changes are quite small

juhoteperi23:09:35

Now boot-reload only misses feature to reconnect to the server after Boot is closed and reopened simple_smile

juhoteperi23:09:22

That would be last feature we are missing in comparison to Figwheel, I think