Fork me on GitHub
#boot
<
2017-02-17
>
samestep00:02:03

@residentsummer That is indeed a troublesome issue! I'm looking into it atm; I'll let you know if I find a solution

samestep02:02:35

@residentsummer Sorry about taking so long; anyway, it turns out this is a really easy fix: instead of running boot repl and then evaluating (boot (watch) (refresh)) in that REPL, just start off the whole thing at once using boot repl -s watch refresh! Then you should get more informative stack traces.

mobileink06:02:29

I’ve run into trouble with boot-cljs. with optimizations none, the paths in the main js file are relative; they look like this:

if(typeof goog == "undefined") document.write('<script src="greetings_hello.out/goog/base.js"></script>');
document.write('<script src="greetings_hello.out/cljs_deps.js"></script>');
But I need absolute paths, since my code is componentized and must be runnable from any page. However using :asset-path results in loss of the “greetings_hello.out” bit.

mobileink06:02:52

For example, if I set :asset-path “resources” (in my cljs.edn file) the result is:

if(typeof goog == "undefined") document.write('<script src="resources/goog/base.js"></script>');
document.write('<script src="resources/cljs_deps.js"></script>');

mobileink06:02:57

And similar if I use “/resources”. But ”resources/goog/base.js" does not match the structure, the code is still in e.g. greetings_hello.out/goog/base.js.

mobileink07:02:01

It looks like this is just the way the Clojurescript compiler operates. If you set :asset-path, it will affect what gets written in the main js file, but it will not effect output-to or output-dir; the implicit assumption is that you will move the files as needed.

mobileink07:02:47

But you can make this work by setting all three options, e.g.

(cljs.build.api/build "src"
  {:main 'hello-world.core
   :asset-path "/resources"
   :output-dir "resources"
   :output-to "resources/main.js"})

mobileink07:02:07

So I need some way to tell boot-cljs to make the output dir and output-to match the asset-path.

mobileink06:02:20

It all works with :optimizations :advanced, but that’s way too slow for dev.

residentsummer06:02:53

@samestep thank you very much, that helped!

qqq10:02:49

using boot, is it possible to "pass an arg from build.boot to a cljs file" ?

qqq10:02:16

so I have an ip address which build.boot knows , but I don't want to ahrd code into a cljs file -- I want build.boot , when it calls cljs-repl or cljs, to somethow pass this info as an argument

martinklepsch10:02:50

@qqq there are two options to do that. One is to use :closure-defines (a cljs compiler option) the other is to use a macro that reads the value from boot.user or from an env var

qqq10:02:16

@martinklepsch : so my laptop ahs a dynamic ip, so build.boot ahs a function (get-ip) opt1 = pass it via :closure-defines ... (get-ip) opt2 = put get-ip in a *.clj file as a macro, then have cljs expand it at compile time? clever; thanks!

qqq10:02:27

@martinklepsch : apparently this blogger is #4 on google for "closure defines boot" https://www.martinklepsch.org/posts/parameterizing-clojurescript-builds.html

martinklepsch10:02:02

should be #1 😛

qqq10:02:35

actually wait, it should be off the front page

qqq10:02:38

it's leiningen, not boot

qqq10:02:01

where in my build.boot do I put:

:closure-defines {'your.app/api-uri ""}
?

martinklepsch10:02:33

it doesn’t have to do anything with lein or boot really. :closure-defines is a compiler option that you can pass to boot-cljs via :compiler-options

qqq10:02:29

okay, so one of my tasks becomes:

(comp
  (watch)
  ...
  (cljs :compiler-options {:closure-defines {'foo "some-constant"}))
?

martinklepsch10:02:02

that seems about right

qqq10:02:13

Fixed the wiki. :closure-defines currently only work under a compilation mode, i.e. a higher setting than :none.
https://groups.google.com/forum/#!topic/clojurescript/7wAO_GzsITM gah

qqq10:02:57

@martinklepsch : it all works now! I forgot the goog-define, which is important to trigger a @define; thanks for all your help at this weird hour

martinklepsch10:02:21

> Fixed the wiki. :closure-defines currently only work under a compilation mode, i.e. a higher setting than :none. That is old and it should work with :none

martinklepsch10:02:35

@qqq it’s approaching 6pm where I am so you’re welcome 😛

qqq11:02:05

yeah, it works now, wiki apparently is out dated, and the problem is I was missing the goog-define

mobileink15:02:57

I’ve got a patch for boot-cljs enabling user-defined :output-dir and :output-to. I know this comes up occasionally, so before I file an issue and submit a PR I’d like to know what the outcome of those discussions was. In particular, is there some reason to not support this? Thx.

mobileink15:02:15

PS the patch does this in a boot-aware way, of course, dealing with tmp dirs etc.

juhoteperi15:02:10

Well, I'm not completely happy about the current status because of problems with asset-path etc, so I might accept this

juhoteperi15:02:22

But my opinion still is that the .cljs.edn file is good practice

juhoteperi15:02:50

First, it allows changing the configuration without restarting the build process

juhoteperi15:02:40

And at least in theory, the file path should allow automatically setting several options, in addition to Cljs :output-dir and :output-to, boot-reload also uses it

mobileink15:02:47

Yes, I mean setting :output-dir and :output-to in the .cljs.edn files.

mobileink15:02:39

Here’s an example:

{:require [miraj.demo.greetings.greetings-hello.core],
 :init-fns [],
 :compiler-options {:optimizations :none,
                    :asset-path "/miraj/demo/greetings",
                    :output-dir "miraj/demo/greetings",
                    :output-to "miraj/demo/greetings/greetings_hello.js"}}

mobileink15:02:44

This allows me to jar up my code and use it on any webpage by just :require-ing it. My index.html has

<script src="/miraj/demo/greetings/greetings_hello.js"></script>

juhoteperi15:02:07

Probably that would also work without .cljs.edn file as in that case the .cljs.edn is created using task options

mobileink15:02:01

Hmm, yeah, why not? I haven’t added cmd line options but that should work as well. It’s really just path manipulation.

juhoteperi15:02:26

Doesn't need new task options, compiler-options is already one option so these can be provided through that

mobileink15:02:46

haven’t tested that though.

juhoteperi15:02:13

Yeah, I'm open to this change, seems like good idea to allow overwriting any compiler-options, but defaulting to Boot-cljs values

juhoteperi15:02:23

I hope to allow the same with :main option

mobileink15:02:16

it’s still rough (bunch of dbug stuff) but the changes are pretty straightforward.

juhoteperi15:02:27

yeah, mostly just change to main to only set the options if they don't already have values

mobileink15:02:55

yep, and slap the output-x args on the end of the working tmp-dir.

phreed16:02:03

re: boot port to dotnet and nuget repositories One of the daunting issues is re-implementing POD without class loaders. I did a look through the boot source and the only place I found that used make-pod was the aot task. That seems to imply that I could do a first pass without POD? Am I missing something?

alandipert16:02:15

most of the dependencies used by the builtin tasks are run in the 'worker pod' which is started there

alandipert16:02:24

in https://github.com/boot-clj/boot/blob/master/boot/core/src/boot/task/built_in.clj you can search for eg pod/with-call-worker to see uses of the worker pod

alandipert16:02:12

of course, many of these tasks are doing things that are maybe irrelevant in c#. but the basic idea is to keep the dependencies of tasks out of userspace

mobileink19:02:30

is there any way to get boot-reload or similar to reload javascript? my clojurescript is already compiled by the time i need a reload - its in a checkout jar.

micha19:02:29

with checkouts a javascript file changing should trigger a rebuild

micha19:02:36

which would bump the reloader

micha19:02:59

do you not see the js file being sent to the client?

mobileink19:02:17

what do you mean by rebuild? explode the jar?

micha19:02:28

that happens automatically yes

micha19:02:40

but additionally the watch task should get triggered

micha19:02:49

which would then run the rest of the pipeline

mobileink19:02:28

my understanding is that the reload task will reload the clojurescript, not the javascript?

micha19:02:06

it can't reload clojurescript in the client

micha19:02:19

it can only reload js, no cljs compiler in the client

mobileink19:02:51

cljs gets recompiled in the local repl, resulting js is sent to browser.

micha19:02:10

and reload reloads the js

mobileink19:02:14

i'm not entirely clear on the cljs repl thing.

micha19:02:52

first thing to check is whether the js file is being sent to the cilent via the websocket

micha19:02:03

there should be a log of files sent in the js console

mobileink19:02:57

let's say i have javascript in my sources, not clojurescript. would reload do anything with it?

micha19:02:05

i think so yes

micha19:02:17

reload doesn't know anything about clojurescript

micha19:02:26

since the browser doesn't know anything about it

micha19:02:50

clojurescript doesn't exist as far as the browser is concerned

mobileink19:02:21

ok, i misunderstood reload. sounds like its already what i need. (sorry, not at my machine atm.)

mobileink19:02:51

but the readme says the reload task must precede the cljs task. shouldn't it be the other way round?

bhagany20:02:02

reload needs to inject some code into the cljs build, which is the reason for that ordering

mobileink20:02:27

then how can it reload the result? i must be missing sth.

mobileink20:02:58

wait. the following cljs task changes the js, which triggers the watch task again, so the next reload picks it up? and the next cljs does not change anything, so the loop exits?

bhagany20:02:00

I think that's close, but it's more like - a file change triggers watch, which re-runs reload, which sends a signal over the websocket to tell the frontend to refresh certain files

mobileink20:02:37

yeah, but if i only changed my cljs, and task cljs has not yet run, there is no change in the js files to pick up, no?

bhagany20:02:03

reload does the websocket stuff as a post-task

bhagany20:02:24

so, that is, after all the js has actually changed

mobileink20:02:51

there must be sth fiendishly clever going on.

bhagany20:02:15

nah, it's not that fiendish. Are you familiar with the pre- and post- tasks?

mobileink20:02:54

nope! i guess a post task waits until the task is over and then runs?

bhagany20:02:31

well, you can think of it that way, but any boot task can do stuff before the rest of the chain runs, or after

bhagany20:02:43

as a result of the middleware pattern

bhagany20:02:13

that line is where reload calls the rest of the task chain

bhagany20:02:38

the stuff before that line happens before the rest of the chain has run, and the stuff after it happens after the rest of the chain has run

mobileink20:02:14

well, i know (or thought i knew) about e.g. wrap-pre, etc.

juhoteperi20:02:34

Boot uses middleware pattern just like Ring

bhagany20:02:39

yes, that's what I was referring to. those macros are just convenience wrappers that implement partial middleware patterns

mobileink20:02:27

of course. i keep forgetting about that, never saw a reason to use it. boot-reload is a great use case.

mobileink20:02:27

if that does not count as fiendishly clever i don't know what does! 😄

bhagany20:02:04

heh, I guess it doesn't seem so fiendish if you've been using middleware for a long time 🙂

mobileink20:02:26

that's another one of those conceptual hurdles. i generally think of the pipeline as one-way, but it's actually two-way. or rather it's a pair of pipelines running in opposite directions.

bhagany20:02:04

yes, I think you've got it

mobileink20:02:51

this is the first time i've come across a case where doing sth "on the way back" makes sense. got any other cases?

mobileink20:02:33

i mean this is seriously cool.

mobileink20:02:06

i'm going to have to reanalyze my tasklibs.

bhagany20:02:11

hmm, I think all of my personal stuff uses with-pre-wrap, or the non-macro equivalent... I would assume that's how most tasks work

bhagany20:02:23

to answer directly, nothing comes to mind

mobileink20:02:15

"do this now, on the way in, and then do that later, on the way out." awesome.

mobileink20:02:53

that opens up all kinds of interesting possibilities.

mobileink20:02:15

wish i had the time to write a serious book on boot.

cpmcdaniel20:02:26

does boot support running pipelines in parallel?

pesterhazy20:02:54

not without trickery, I don't think

cpmcdaniel20:02:38

for example, our project has UI and backend builds that could happen concurrently. Just wondering if it was possible to do in parallel without multiple JVM instances

richiardiandrea21:02:51

@cpmcdaniel there is a boot.parallel ns to try out and report me, I think you could be the first one who uses it 🙂

mobileink21:02:24

richiardiandrea: link?

richiardiandrea21:02:07

It is a namespace in boot so you can just require it. an example usage is boot.test.

cpmcdaniel21:02:09

sounds like a nice holiday project