Fork me on GitHub
#boot
<
2016-09-15
>
spieden00:09:17

is there any way to log what’s added to a fileset and when? i can see the files produced by a task in the cache, and there are add-resource and commit! calls after they’re created, but sift gives the ever helpful

No implementation of method: :file of protocol: #'boot.tmpdir/ITmpFile found for class: nil

spieden00:09:38

wish sift would show what is there so i can debug

micha00:09:53

can you paste how you call sift?

spieden00:09:56

been trying to step through at the repl, but the laziness is boggling me

spieden00:09:11

(extra requires were to get symbols resolving in cursive)

micha00:09:42

hm, can you paste the stack trace too?

micha00:09:54

it's very strange to get that kind of exception

spieden00:09:33

Sifting output files...
        clojure.lang.ExceptionInfo: No implementation of method: :file of protocol: #'boot.tmpdir/ITmpFile found for class: nil
    data: {:file
           "/var/folders/3y/6pws2t7168l1c228pv16scvw0000gn/T/boot.user879892176421800489.clj",
           :line 31}
java.lang.IllegalArgumentException: No implementation of method: :file of protocol: #'boot.tmpdir/ITmpFile found for class: nil
              clojure.core/-cache-protocol-fn                 core_deftype.clj:  554
                             boot.tmpdir/fn/G                       tmpdir.clj:   25
                           boot.core/tmp-file                         core.clj:  381
cljsjs.boot-cljsjs.packaging/eval379/fn/fn/fn                    packaging.clj:  148
               boot.task.built-in/fn/fn/fn/fn                     built_in.clj:  493
                   boot.user/eval470/fn/fn/fn  boot.user879892176421800489.clj:   25
cljsjs.boot-cljsjs.packaging/eval178/fn/fn/fn                    packaging.clj:   40
cljsjs.boot-cljsjs.packaging/eval127/fn/fn/fn                    packaging.clj:   25
 cljsjs.boot-cljsjs.packaging/eval290/fn/G/fn                    packaging.clj:   86
                          boot.core/run-tasks                         core.clj:  938
                            boot.core/boot/fn                         core.clj:  948
          clojure.core/binding-conveyor-fn/fn                         core.clj: 1916
                                          …

spieden00:09:40

.. aaand suddenly it’s working, hrm

spieden00:09:47

bbl thanks for looking

micha00:09:30

@spieden i see the problem i think

micha00:09:59

if there are no matches there that line will blow up

micha00:09:21

i think boot.core/tmp-file should perform a nil check perhaps

micha00:09:23

i can't understand how the minify task was being called

micha00:09:36

but that stacktrace definitely looks like it blew up in there

kenbier01:09:40

is anyone using joplin from a boot task? curious how its done

spieden03:09:50

@micha it was minify lines that whole time while I thought it was the sift ones 😬 should have read the trace but a nicer message wouldn't have hurt

onetom12:09:56

im just looking into mattermost for our internal use. i remember there some conversations around where to move the clojurians team later, since slack didnt want to support open source communities or something like that. there was #braid-chat #clojurian-chat-app etc what was the conclusion? does anyone know/remember?

onetom12:09:38

also is there any counter recommendation on mattermost?

onetom12:09:23

(i saw https://hackpad.com/collection/wnikaeBENEE in a topic message, so im looking into that now)

onetom13:09:16

@anmonteiro so discord is not open source but then i also dont see any pricing page πŸ˜•

onetom13:09:35

looks very powerful otherwise; thx for the mention. haven't heard about it before

onetom13:09:51

i only used teamspeak and mumble in this category

anmonteiro13:09:49

@onetom oh I probably didn’t realise you were looking for an open source thing

anmonteiro13:09:25

so the React community moved to Discord after their Slack grew beyond a certain point

onetom13:09:29

no, not necessarily

onetom13:09:34

that's why im asking about pricing

anmonteiro13:09:23

for me the problem of Discord is that it still doesn’t have a search feature

anmonteiro13:09:30

but I think they’re working on that

onetom13:09:12

@anmonteiro is there a clojurians ?server? on discord yet?

anmonteiro13:09:23

not that I know of

vikeri14:09:13

@onetom: There is also https://rocket.chat/

vikeri14:09:58

and the nerdier (distributed) https://matrix.org/ (Matrix protocol) which has a separate client: https://vector.im/

onetom14:09:29

@vikeri all of these has been mentioned on https://hackpad.com/Home-YVTdpH47Vz4 with pros and cons and https://github.com/reactiflux/volunteers/issues/25 page has even more info on the topic

vikeri14:09:33

@onetom sorry, missed that. Came into the conversation without reading it in full

coyotespike15:09:29

Hi, boot noob here. I ran lein new luminus +reframe +postgres +auth, and then tried to convert to boot. Now it runs successfully, but returns a 404 page. Does anyone have any tips or an example of a simple boot configuration with both Clj and CLJS?

coyotespike15:09:58

I also like this boot project - it has Reagent and DevCards! https://github.com/jupl/closcri/tree/reagent

anmonteiro15:09:37

@coyotespike here’s a very simple project with a Boot config for client + server

coyotespike15:09:37

But like Tenzing, it doesn't have a backend.

coyotespike15:09:55

@anmonteiro Thank you!

coyotespike15:09:43

Probably a dumb question: on line 59 of build.boot, you have (system :sys #'dev-system :auto true :files ["server.clj" "parser.clj"]). Is this where the whole "server hosts the html where ClojureScript lives" thing gets started?

anmonteiro15:09:59

@coyotespike oh right, probably not that a beginner-friendly project after alll

coyotespike15:09:20

well, depending on the beginner πŸ˜‰

coyotespike15:09:26

I was just about to ask about that

coyotespike16:09:09

How do you like System? I haven't yet wrapped my head around it - it's for managing database, server, etc, right?

anmonteiro16:09:49

it’s mostly a reloaded integration for sierra’s Component library

anmonteiro16:09:04

I fought it for a while but now it’s the first thing I add to any project that has a server πŸ™‚

coyotespike16:09:34

So it effectively replaces the project.clj calls to yourapp.core to bootstrap the whole thing, among other tasks

coyotespike16:09:10

Meaning if I try to translate directly from project.clj, I am not being very Boot-y and should instead learn the System/Component way of running the whole shebang.

anmonteiro16:09:24

that would be one way to do it, yes

coyotespike16:09:11

Well, if I learn that instead of trying to make it go the old way, that'll be much more productive. Thanks! 😎

stathissideris16:09:13

It’s not immediately obvious from the documentation: does boot have the concept of a task that depends on other tasks. Like B depends on A, so if try to run B it will automatically run A first

domkm16:09:44

@stathissideris Tasks are just functions. Task B can run Task A first.

micha16:09:47

you basically use comp there

stathissideris16:09:33

@domkm ok, so it’s not explicit like in β€œmake" for example

stathissideris16:09:38

I mean Makefiles

smw16:09:06

so basically you make a task C that’s named whatever you were going to name B

smw16:09:51

and then deftask C as (comp (A) (B))

micha16:09:59

@stathissideris i like to see it the otherway--it's very explicit because you just type them in order πŸ™‚

micha16:09:15

rather than implicitly decided by the tool

stathissideris16:09:03

thanks all, that’s very clear

stathissideris16:09:17

I think it’s not time for boot yet for me πŸ™‚

smw16:09:49

My experience is, for the most part, things I’ve struggled with for hours in lein have just worked in boot.

micha16:09:16

haha and sometimes vice versa πŸ˜‰

onetom16:09:39

micha, it's interesting u wrote "just type them in order", because how they run depends on what the task do before and after calling the next task... i think it's a general drawback of the middleware pattern though...

micha16:09:09

@onetom the dependency order is strictly defined by the order in which you comp them though

onetom16:09:54

what does "dependency order" mean though and why is it useful versus in what order will they run?

micha16:09:10

well consider make for example, or maven, or leiningen, etc

micha16:09:30

you make tasks, and in the task definition you assign a sort of priority

micha16:09:43

and the tool figures out a DAG and runs the tasks in dependency order

onetom16:09:47

good example is the (serve) task which i can just put at the beginning or the end and no practical difference

onetom16:09:57

(at least i still didn't understand what is the difference)

micha16:09:15

so like in leiningen the jar task depends on the compile task

micha16:09:16

and so on

micha16:09:32

so you just type lein jar and it compiles stuff too

micha16:09:41

based on the dependency metadata on the tasks

onetom16:09:04

yup, i get that. the task has dependencies built into its definition explicitely in lein

micha16:09:19

right, in boot you do that yourself via comp

micha16:09:06

some tasks are not affected by other tasks, like the serve task

micha16:09:19

because it's just for side effects and is totally asynchronous

micha16:09:38

it's not actually doing any work

micha16:09:46

sort of like an attached debugger in a way

micha16:09:20

the serve task is a task that just observes the running build, in a way

onetom16:09:39

what i mean is this:

(deftask t1-post []
  (fn [next]
    (fn [fs]
      (let [fs* (next fs)]
        (println "T1")
        fs*))))

(deftask t1-pre []
  (fn [next]
    (fn [fs]
      (println "T1")
      (next fs))))

(deftask t2 []
  (fn [next]
    (fn [fs]
      (println "T2")
      (next fs))))

(deftask t-ok []
  (comp (t1-pre) (t2)))

(deftask t-suprise []
  (comp (t1-post) (t2)))

onetom16:09:13

This gives:

> boot t-ok
T1
T2
vs
> boot t-suprise
T2
T1

onetom16:09:46

and there is no way to know if a task is doing it's job before or after calling the next handler

micha16:09:14

that's only for side effects

micha16:09:33

tasks do not do work on the post phase

onetom16:09:51

so do they depend on each other? ... isn't dependency something which should correlate with run order? ...

micha16:09:56

if you use with-post-wrap an exception will be thrown if you do

micha16:09:22

they depend on each other if you comp them in that order

micha16:09:33

because the output of one is fed into the input of the other

onetom16:09:24

if you make the tasks consistently with with-pre-wrap, sure...

martinklepsch16:09:32

@micha I wonder, have you ever looked at interceptors?

micha16:09:43

that is the only place you can modify the fileset, in the pre phase

martinklepsch16:09:52

I for the first time ever understood them when reading the latest re-frame docs and they seem kinda cool, dunno if there's much application for them with boot but figured I might bring it to your attention anyways πŸ™‚

micha16:09:00

what would be gained there?

micha16:09:40

but yes, i've received some good ideas about how to make boot tasks more flexible

micha16:09:54

from luke at cognitect and rich

micha16:09:12

like for instance separating the control flow aspect of tasks from the work

micha16:09:40

like the worker part could be a function that takes a fileset and returns a fileset after doing work

micha16:09:59

then a separate object could wrap that into a middleware

martinklepsch16:09:02

no clear "oh we'd get this" but one thing that came to mind is being able to inspect the task queue, which could be used to check show warnings if a cljs task is used before a reload task etc

micha16:09:03

or an interceptor

martinklepsch16:09:20

probably you can also do evil things with that knowledge but Β―\(ツ)/Β―

micha16:09:45

my approach to that is to make the tasks themselves well factored enough so that it's clear to the user how to order them

micha16:09:59

that's the real win, imho

micha16:09:12

having tools to help you only goes so far

micha16:09:22

eliminating that complexity entirely is what i aim for

martinklepsch16:09:25

well putting speak first when the audible notification is after the build is something that's still counterintuitive

micha16:09:03

maybe a way to visualize how the message flows through the pipeline would be good there

micha16:09:22

so you can see that if the speak task is at the end and an exception is thrown

martinklepsch16:09:24

but yeah I think I get what you mean, just thinking that it could perhaps improve error messages

micha16:09:31

you can see that the message never gets to the speak task

micha16:09:34

@martinklepsch i think you're right about getting visibility into the pipeline

micha16:09:48

we shouldn't have to imagine it, we can show it

richiardiandrea17:09:11

about that, an approach can be to have declarative data from which you build your tasks, kind of like re-frame is doing: a map will contain all the info you need in order to declare a task. It will also contain a symbol or var that points to the "worker"...everything is data right...I think Onyx took this approach for its distributed computations

richiardiandrea17:09:46

nothing new I guess πŸ˜„

micha17:09:06

everything doesn't have to be data πŸ™‚

micha17:09:14

we need functions too

richiardiandrea17:09:55

yep, the solution in Onyx is to include vars to functions

martinklepsch17:09:26

right but onyx and re-frame are also still pretty different in how they do it

micha17:09:44

yeah onyx is also distributed

martinklepsch17:09:49

like onyx has the ID "approach" vs. re-frame which has a map that has functions as values

micha17:09:52

so you need to be able to send things over the wire

martinklepsch17:09:03

yeah, different constraints,sure

micha17:09:11

and that demands data

richiardiandrea17:09:15

yes different but similar

martinklepsch17:09:30

I find re-frame's data abstraction pretty light actually as in 99% of the functionality is still functions

martinklepsch17:09:39

just the way these are composed is based on data

richiardiandrea17:09:49

also, re-frame already had the contraint to keep everything as an event system

richiardiandrea17:09:16

so interceptors/middlewares are a natural fit there

micha17:09:35

separating the flow from the work will let you create your own kind of pipeline if you want, but can still be backward compatible

micha17:09:56

like you can take a fn that does the work and make a task like the ones we have now like this:

micha17:09:14

(deftask foo
  []
  (with-pre-wrap fileset
    (-> (fn-that-does-the-work fileset) commit!)))

micha17:09:09

but you could also have interceptors if you want, and have definterceptortask

micha17:09:21

using the same fn-that-does-the-work

micha17:09:29

well in theory, perhaps

richiardiandrea17:09:04

yeah I guess you need something like that if you want to visualize the pipeline...you need some way to connect the dots

richiardiandrea17:09:32

also, when you connect the dots you can detect things that can be run in parallel

richiardiandrea17:09:41

and use boot-in-boot automagically

micha17:09:17

perhaps, although i am less optimistic there

micha17:09:39

computers trying to figure out how to optimize your build seems like it will add a lot of complexity

micha17:09:45

like "what is it doing now"

richiardiandrea17:09:58

mmm yeah maybe yes

micha17:09:04

it's nice that it's very simple and easy to understand exactly what's happening now

richiardiandrea17:09:56

also, I noticed that with real codebases creating a pod is still something expensive so I don't really think we would gain something there

micha17:09:31

you mean like creating a pod for each task to run in?

richiardiandrea17:09:58

no well, use boot.parallel for tasks that can run in parallel...the gain might not be as high as I expect...and in fact I am also wondering if I should switch from boot.test to boot-alt-test myself..the pod creation startup time is getting unberable while running tests in my middle-sized codebase

richiardiandrea17:09:35

(meaning, not that big code base :D)

micha17:09:39

yeah the pods are a tradeoff there

micha17:09:45

maybe not a good one

micha17:09:10

the pods are so you don't need to restart, but if it's slow it's like you're restarting all the time anyway

richiardiandrea17:09:38

anyway, it's all good, just wondering if pod is the way to go for tests anyways πŸ˜„

micha17:09:51

yeah that could be a failed experiment

richiardiandrea17:09:55

I am starting to agree yes

coyotespike18:09:04

I'm pretty puzzled, as I'm following another project. It all builds, but nothing shows on the page.

coyotespike18:09:30

Basically, after changing om in core to your basic reagent/render, shouldn't boot just compile the CLJS as before?

coyotespike18:09:13

I also added index.cljs.edn under resources, with:

{:require [holy-grail.core]
 :init-fns [holy-grail.core/render]

 :compiler-options {:asset-path "js/main.out"}}

yury.solovyov19:09:50

Project tree looks like this:

β”œβ”€β”€ boot.properties
β”œβ”€β”€ build.boot
β”œβ”€β”€ LICENSE
β”œβ”€β”€ project.clj
β”œβ”€β”€ README.md
β”œβ”€β”€ resources
β”‚Β Β  β”œβ”€β”€ index.html
β”‚Β Β  β”œβ”€β”€ main.cljs.edn
β”‚Β Β  β”œβ”€β”€ package.json
β”‚Β Β  └── renderer.cljs.edn
β”œβ”€β”€ src
β”‚Β Β  └── eion
β”‚Β Β      β”œβ”€β”€ directories
β”‚Β Β      β”‚Β Β  └── core.cljs
β”‚Β Β      β”œβ”€β”€ main
β”‚Β Β      β”‚Β Β  └── core.cljs
β”‚Β Β      └── renderer
β”‚Β Β          └── core.cljs

martinklepsch19:09:23

the content of the .cljs.edn files might also be interesting

micha19:09:36

is the reload task before the cljs task, also?

martinklepsch19:09:25

@coyotespike this needs a bit more info πŸ™‚ ideally a repo with code but an error message or your namespace might also help

yury.solovyov19:09:29

namespaces are mapped to dir structure

micha19:09:33

ah, i don't think reload and nodejs mix well

micha19:09:45

not 100% sure of that

yury.solovyov19:09:50

I can comment it out to try

yury.solovyov19:09:04

new one: adzerk.boot_cljs.util.proxy$clojure.lang.ExceptionInfo$ff19274a: ERROR: No such namespace: eion.renderer.out.cljs.core.async.impl.timers

micha19:09:40

do you have your dependencies set up in your build.boot?

micha19:09:46

looks like you're missing some deps maybe

coyotespike19:09:32

@martinklepsch cool πŸ™‚ I'll throw up a repo and come right back with a summary.

martinklepsch19:09:56

@yury.solovyov the IDs in dev-build are still wrong

yury.solovyov19:09:23

should I add .core ?

martinklepsch19:09:25

they need to be just main and renderer

yury.solovyov19:09:42

and for cljs-repl ?

martinklepsch19:09:09

as I said in DM, the IDs are path to a .cljs.edn file relative to your (in this case) resources/directory

martinklepsch19:09:21

they all expect the same thing

martinklepsch19:09:36

build IDs have nothing to do with namespaces

coyotespike19:09:58

Actually the relevant dev task looks like:

(deftask dev
  "Run a restartable system in the Repl"
  []
  (comp
   (environ :env {:http-port "3000"})
   (watch :verbose true)
   (system :sys #'dev-system :auto true :files ["handler.clj"])
   (reload)
 
   (cljs :source-map true
         :optimizations :none)
   (sift :include #{#"\.cljs\.edn$"} :invert true)
   (repl :server true)
   (speak)))

coyotespike19:09:19

So reload comes before cljs task.

coyotespike19:09:37

If I just drop (js/alert "Hello") at the bottom of the file core.cljs, it fires off on the page. So the file is getting looked at, but I am not hooking the cljsbuild in correctly.

yury.solovyov19:09:54

the only problem left is that it outputs to target/renderer.out and target/main.out, can I make it drop .out thing?

martinklepsch19:09:15

@coyotespike so you add some code and it's evaluated in the browser, yes? what are you missing?

martinklepsch19:09:33

@yury.solovyov you can but really you don't want to

martinklepsch19:09:42

usually you don't even see this

martinklepsch19:09:10

@yury.solovyov when you build a single file (`:advanced`) the contents of these directories become irrelevant

coyotespike19:09:26

Hmm... I'm missing my compiled ClojureScript - HTML and JS. So I I thought I hadn't directed Boot to the right init function.

martinklepsch19:09:15

@coyotespike ah, so you see a toplevel thing being executed but your app function is not called

coyotespike19:09:52

But (reagent/render [component] (.getElementByID js/document "container")) by itself didn't do anything.

martinklepsch19:09:59

@coyotespike so actually your cljs.edn file looks correct

martinklepsch19:09:10

maybe the container element is missing?

coyotespike19:09:12

The next thing I was going to bring up πŸ™‚

coyotespike19:09:57

And the cljs.edn file is a default, right? I haven't specified it in my boot.build

martinklepsch19:09:55

yes, the cljs task will pick it up automatically

martinklepsch19:09:31

@coyotespike just cloned your repo but when I go to localhost:3000 I get "Failed to load resource: the server responded with a status of 404 (Not Found)" (for loading main.js)

martinklepsch19:09:51

can you push your current setup?

coyotespike19:09:11

sorry, yes, one sec

coyotespike19:09:27

@martinklepsch right, should be good now

martinklepsch19:09:29

@coyotespike still same problem πŸ˜„

coyotespike19:09:12

I cloned into a new directory to run it, and it went

coyotespike19:09:42

by which i mean, nothing on the page, but no 404 either

martinklepsch19:09:14

@coyotespike not even in the console?

coyotespike19:09:28

dam you're right, it does show that in the console

coyotespike20:09:24

well that's good to know

martinklepsch20:09:42

so the issue is you try to load main.js but because you have index.cljs.edn your output file will be named index.js

coyotespike20:09:13

Dude, thanks so much

coyotespike20:09:35

I need to fix some reagent now but I can figure that out πŸ™‚

coyotespike20:09:18

I am trying to get my own little template set up with Boot, DevCards, System, buddy for auth, postgres....so first I need to learn me some Boot

martinklepsch20:09:22

@coyotespike glad we figured it out πŸ™‚ For some reason the ReactDOM related error you might be seeing right now is caused by the Om dependency

martinklepsch20:09:33

so once you remove that it should all work (tm)

coyotespike20:09:19

I was wondering about that πŸ™‚ goodbye Om 😎

yury.solovyov20:09:09

is that ok that adzerk.boot-cljs-repl adzerk.boot-reload use document.write?

yury.solovyov20:09:49

I mean renderer.js look like so

var CLOSURE_UNCOMPILED_DEFINES = null;
if(typeof goog == "undefined") document.write('<script src="renderer.out/goog/base.js"></script>');
document.write('<script src="renderer.out/cljs_deps.js"></script>');
document.write('<script>if (typeof goog == "undefined") console.warn("ClojureScript could not load :main, did you forget to specify :asset-path?");</script>');
document.write('<script>goog.require("boot.cljs.main8477");</script>');

yury.solovyov20:09:40

and document.write it 100% not the most proper way to add scripts

micha20:09:54

that's the standard way for goog closure to do it

micha20:09:12

when you have requires and without optimizations

micha20:09:39

when you deploy to production you'll have at least whitespace optimizations on, and none of that will be there anymore

yury.solovyov20:09:30

I wonder if it would be better to enable simple optimizations, but I'm not sure hot reloading would still work

micha20:09:06

you can't reload with optimizations on really

micha20:09:14

because all the js is combined in one file

yury.solovyov20:09:05

btw, thanks for help with boot, it seems to work

martinklepsch20:09:51

@yury.solovyov also the biggest drawback of :simple is that compile times are easily going to be 10 times higher than without optimizations

yury.solovyov20:09:54

noticed that with lein

yury.solovyov20:09:37

i tried to set up figwheel, but gave up

martinklepsch21:09:23

is there any way to have a boot repl and watch in the same pipeline with the repl being usable without separate client

smw21:09:41

just don’t put :server true as an argument to repl?

micha21:09:53

sure, you can run (boot (watch) ... from the repl

smw21:09:59

(deftask devlocal
  "Run a restartable system in the Repl"
  []
  (comp
   (environ :env {:http-port "3000"})
   (watch :verbose true)
   (system :sys #'dev-system :auto true :files ["systems.clj" "core.clj"])
   (repl)))

smw21:09:05

this seems to work?

micha21:09:03

does that work?

micha21:09:22

i would have thought the repl client would block the pipeline there?

martinklepsch21:09:45

I always forget you can run tasks from the REPL lol

micha21:09:32

boot.user=> (def p (future (boot (watch) ...)))
...
boot.user=> @p
;; now you can press ctrl-c to end the pipeline

smw21:09:17

seems like it works. I don’t use it often that way, since I tend to use repl via cursive.

micha21:09:22

@smw if you update a source file does the watcher fire?

smw21:09:06

no, I guess not.

smw21:09:11

well strange.

smw21:09:32

need some way to run task in bg?

micha21:09:07

yeah i think you need to run it in the repl if you want to have only one jvm

micha21:09:25

in a future so it runs in the background

smw21:09:41

can’t do future from build.boot?

micha21:09:51

sure, you can

micha21:09:07

also a good approach

smw21:09:16

wonder if it should be an arg to watch

micha21:09:42

it needs to be done outside the pipeline i think

micha21:09:07

like youd have in your build.boot (def p (future (boot (watch) (foo) (bar))))

micha21:09:13

then you could do boot repl

micha21:09:25

and you'd have the build going async in the background

martinklepsch21:09:46

what happens when you then do a second (boot ...) thing?

martinklepsch21:09:23

that future approach seems cool β€” will use πŸ‘Œ

micha21:09:00

yes you don't want to do two of those lol

micha21:09:36

and weird stuff also happens if you do (boot (repl)) from the repl

micha21:09:50

it's a pretty #yolo type of situation

martinklepsch21:09:12

ha, that's what I guessed πŸ˜„

coyotespike21:09:49

So now I'm trying to add DevCards. It's complaining No such namespace: devcards.out.cljs.core.async.impl.channels. I think the error lies in devcards.cljs.edn.

{:require [holy-grail.components.page-test]
 :init-fns [devcards.core/start-devcard-ui!]}
I also tried it like:
{:require [holy-grail.components.page-test]
 :init-fns [holy-grail.components.page-test/devcards]}

coyotespike21:09:22

The devcards task is quite simple:

(deftask devcards []
  (comp
   (speak)
   (sift :include #{#"^index"} :invert true)
   (cljs :optimizations :advanced
         :compiler-options {:devcards true})
   (sift :include #{#"\.out" #"\.cljs\.edn$" #"^\." #"/\."} :invert true)))

juhoteperi21:09:18

That looks like what would happen if Cljs was trying to compile files in Cljs output-dir

juhoteperi21:09:17

1. Check that boot-cljs finds you .cljs.edn (it is not saying something like "Writing main.cljs.edn" 2. do you have e.g. lein cljsbuild output in your resources folder?

coyotespike21:09:43

Thanks @juhoteperi, will do. That's what I thought it looked like too. I don't have any output in my resources folder.

juhoteperi21:09:26

Aha, it's the first sift task, that removes your cljs.edn file

juhoteperi21:09:02

I don't know. Maybe. That removes any files under index path.

juhoteperi21:09:18

What is the path of cljs.edn file?

coyotespike21:09:46

just /resources/devcards.cljs.edn

coyotespike21:09:06

And same for main.cljs.edn, which is working

juhoteperi21:09:21

Hmm. That not the cause then-

coyotespike21:09:20

When I remove both sifts, the error's still there, so I think you're right.

coyotespike22:09:10

However, this results in devcards.html rendering, though without any cards:

(deftask dev
  "Run a restartable system in the Repl"
  []
  (comp
   (environ :env {:http-port "3000"})
   (watch :verbose true)
   (system :sys #'dev-system :auto true :files ["handler.clj"])

   (reload)
 
   (cljs :source-map true
         :optimizations :none)
   (sift :include #{#"\.cljs\.edn$"} :invert true)
   (repl :server true)
   (speak)))