Fork me on GitHub
#clojurescript
<
2018-04-05
>
darwin00:04:44

I’m not familiar with Google’s Workbox, and I’m not sure what js/self is, but if the library is foreign (not part of your cljs advanced build) you must use string names or externs, that (.-precaching (oget js/self "workbox")) won’t work, because precaching will get minified

zaphodious00:04:10

js/self is the same as js/window in a web worker. And, yes, foreign lib. Turning extern inference on, then.

zaphodious00:04:32

Thanks for the quick answer @darwin. I'd have spent days trying to suss that out 🙂

darwin00:04:36

a side note: I would recommend using goog/global for all your needs of referencing “root” js object regardless of context, if you use externs (inferred or hand-made) then you don’t need to use cljs-oops, I think

zaphodious00:04:06

Thanks, I'll do that

zaphodious00:04:58

Taking a better look into Workbox, it seems the problem comes from the lib dynamically loading stuff. Straight access only, then.

zaphodious00:04:12

At least inference doesn't kick up any warnings 🙂

darwin00:04:45

I just briefly looked at the code generated by (oget js/self "workbox" "precaching") and it looks good to me: https://gist.github.com/darwin/4a69b4f841bd94e225c710e9da602360 there is a lot of diagnostics boilerplate code, but the code really should return self["workbox"]["precaching"]

zaphodious00:04:34

Yep, that's the same that I got. Maybe the Workbox lib only loads on dot access? That would be weird.

zaphodious00:04:00

Ahh, I think I've got it. using workbox.loadModule("precaching") also fails, because (according to the page that's returned when I navigate to the script it attempts to pull down) Anonymous caller does not have storage.objects.get access to workbox-cdn/releases/3.0.1/precaching.dev.js.

zaphodious00:04:15

I think at this point I'm not going to look into it any further. I suppose that as long as extern inference is working, I'm okay? Either way, thanks @darwin 🙂

darwin00:04:34

Good! You should be ok.

zaphodious02:04:29

Extern inference isn't working as well as it initially seemed. Making an externs file. Assuming the names are correct, is this an okay way to do it? The documentation on what's proper is... confusing. WIP, not complete, etc. https://gist.github.com/Zaphodious/4ecf1e559c74601f7eb20c479c38579c

richiardiandrea02:04:07

Can confirm inference does not correctly infers and I needed to drop it

zaphodious02:04:21

Also, is it necessary to add function param information?

justinlee02:04:50

@achythlook Just to make a sanity check: are you compiling with :advanced compilation? Because if not, then externs aren’t your problem.

zaphodious02:04:30

Yep. I'm explicitely doing that to make sure that it works. Works perfectly under :none 🙂

justinlee02:04:09

okay good i just didn’t want you to waste a bunch of time 😉

justinlee02:04:38

hopefully someone else can help with externs. i try to avoid them so i can’t help

zaphodious02:04:38

I was trying to avoid them, but workbox seems to defy my best attempts 😢

zaphodious02:04:36

My current strat is to define the api structure in an extern, and make a wrapper to handle the rest. This ain't going into cljsjs, that's for sure.

justinlee02:04:30

and you’re still getting errors about missing symbols? the exchange you had above with darwin didn’t make any sense to me

zaphodious02:04:47

No more errors as long as I don't use oops

zaphodious02:04:20

It seems that workbox uses its own special-snowflake module loading scheme, which means that I can only access a given namespace the way that they want me to

zaphodious02:04:14

Looking at their source code, they appear to be doing a load of dynamic woo that doesn't really make a bunch of sense to me. It certainly doesn't line up well with their documentation. However, if I call their code the way that the doc wants me to, it works.

zaphodious02:04:27

What really pees in my cheerios is that their npm module just calls their cdn, so I can't even use npm-deps!

zaphodious04:04:07

Can I put arbitrary compiler options in deps.clj? Like, say, :language-in and :rewrite-polyfills?

richiardiandrea05:04:05

@achythlook do you mean compiler options?

richiardiandrea05:04:56

Not in deps.edn but the new cljs.main accepts a -co edn string or file

richiardiandrea05:04:27

Yep you can do clojure -m cljs.main -co your-opts.edn -t browser -c a-namespace.core

richiardiandrea05:04:41

Any compiler option can go in there

richiardiandrea05:04:21

I am on mobile so please excuse typos and fuzzy memory 😅

zaphodious05:04:41

No worries dude. I appreciate the help ya'll are giving me here 🙂

Ykä06:04:38

Hi! Does anyone know if there is any sass library for Clojure that has sass autoprefixer? Or any other way to get that functionality into a Reagent project? We started using sass4clj which apparently does not have it.

zaphodious06:04:58

Off the top of my head, if you're willing to write in EDN there's Garden.

zaphodious06:04:33

I use it. There's no clj to sass compiler that I'm aware of.

juhoteperi06:04:26

@yka Isn't autoprefixer (https://github.com/postcss/autoprefixer) completely separate to sass compiler? I'd guess in JS project one would combine sass and autoprefixer with gulp or something

juhoteperi06:04:55

When using Boot you could combine sass4clj withhttps://github.com/danielsz/boot-autoprefixer, but looks like Lein plugin doesn't exist

juhoteperi06:04:37

You probably just need this for production builds so maybe it would be okay to just use bash script or something to call autopreofixer directly?

sveri07:04:34

Is it somehow expected to replace figwheel with the clj tooling?

sveri07:04:41

Are there any plans? Does that make sense at all?

juhoteperi07:04:50

@sveri I've seen some discussions about Figwheel providing main namespace, similar to new cljs.main, which can be used with clj. I.e. won't be replaced, but Figwheel could be usable with clj in addition to with lein.

sveri07:04:10

@juhoteperi Thanks, I think its interesting to see how that turns out.

akiroz07:04:42

Anyone here has experience using :npm-deps in a large-ish project? It seems like cljs-oss/module-deps will choke on relative require()s with hyphens in the name... for example, it's unable to find require('./locale-data/complete.js') from node_modules/intl/index.js but if I rename locale-data to locale_data it works.

akiroz07:04:10

Is this a known issue? EDIT: ok, it's probably not the hyphen causing the error. let me report back after doing a bit more investigation.....

Ykä07:04:05

@juhoteperi OK. I guess it should be possible to just run npm autoprefixer task via lein as well (?) . We'll just try to hack them together. 😮

Ykä07:04:04

Thanks for the link, maybe we could create a similar lein plugin as the boot-autoprefixer.

juhoteperi07:04:05

I'm not familiar with lein npm tools

Ykä07:04:03

I saw somewhere that one can run bash scripts via lein, so I'm thinking on running it that way so that everyhing would still be run from lein.

soulflyer13:04:31

pretty simple to do, here's an example from descjop. In the aliases section it has this:

"descjop-init" ["do"
                   ["shell" "npm" "install"]
                   ["shell" "grunt" "download-electron"]]

ajs08:04:54

I'm using a symlink in a cljs project to a cljc file in another project directory, and the cljsbuild appears to work fine (and I've tested it is compiling the other cljc file and its fns are working), but before the build is finished, it does report java.io.FileNotFoundException: Could not locate .... foo.foo__init.class with a long stack trace too. Appears to not affect the actual js output. Anyone know why it does this or how to silence the error?

stephenmhopper14:04:18

Hi everybody, I have a question about using memoize in combination with core.async in CLJS. My app is making HTTP calls with cljs-http. Each call returns a core.async channel. Every time I make an HTTP call, I have a handler function that reads from the response channel with <! and then calls swap! on an atom that’s passed in as a parameter. There are certain HTTP calls that I would like to cache. I was trying to essentially wrap the fn that creates the HTTP response channel with`memoize`. This works in some regard as it always returns the same go channel. However, I can only consume the response from the channel once, so I’m back at square one. What’s the best way around this? Is there some way to read from a channel without consuming?

darwin14:04:56

@stephenmhopper I would look into promise-chan, I would keep one atom with a map url -> promise-chan, the caching function would first try to get hit in this map and return promise-chan if avail, or otherwise fire cljs-http request, create promise-chan from it and store it in the map

darwin14:04:32

this way you should properly return in-flight requests from the cache as well (not only completed ones)

stephenmhopper14:04:53

Okay, cool. I’ll look into that. Thank you!

darwin14:04:22

“After a put, all pending takes are notified, and any subsequent takes return the put value immediately”

stephenmhopper14:04:33

@darwin Yeah, I think that’s exactly what I need

stephenmhopper14:04:47

Thank you

🍻 8
stephenmhopper15:04:46

@darwin cljs-http is returning a chan for me. So my memoized request function just returns (async/pipe response-channel-from-cljs-http (async/promise-chan)) and everything works perfectly. Thanks again!

darwin15:04:56

great! I think in ideal world cljs-http should be returning promise-chan for http requests - they have promise semantics, I’m also considering promise-chan to be the default for my chromex library.

justinlee15:04:25

@darwin honest question: if you prefer promise semantics, why not just use promises?

darwin15:04:51

well, I don’t have strong opinion about this, I think it is more natural for cljs libraries to work with core.async as default, it feels more natural than doing promise with callbacks, btw. when I wrote chromex, I didn’t know promise-chan existed

darwin15:04:19

if I were to export some cljs functionality into js land, then I would definitely consider direct use of promises

justinlee15:04:40

thanks. i’m still trying to come to some decisions on how best to deal with async code in cljs. i don’t think i like any of the choices very much 🙂

darwin15:04:05

I like core.async channels, except for debugging experience and some sharp edges

justinlee15:04:21

right. it’s the error handling that is the problem. promises behave nicely.

justinlee15:04:40

i was looking at trying to fix a bug in cljs-http, and it is very hard to do, because you have to carefully wrap every map with a try-catch block to avoid getting your exceptions eaten. I think it would be better to avoid all that and use function composition in a transducer, but suddenly core.async seems full of ugly pitfalls and I don’t feel like I’m expert enough to use it safely

darwin15:04:35

yep, convenient error handling is an issue, but with raw js promises you have to branch via .catch() all the time, this is also inconvenient

darwin16:04:21

with core.async you can at least help yourself with macros, e.g. go-catch and <? tandem

darwin16:04:26

for normal situations I set window.onerror and simply handle all exceptions there, usually exceptions in channels are fatal

stephenmhopper15:04:34

Yeah it certainly makes sense for web requests

octahedrion15:04:58

my code-splitting modules code is nearly working, except that when it attempts to load a module it fails because the path to the module's .js is an absolute file path, not a relative path

octahedrion15:04:09

any idea why ?

octahedrion15:04:29

(the path in the browser console is log:downloadModules ids:mymodule uris:js/Users/me/absolute/file/path/here/to/js/not/relative.js

rads15:04:06

in CLJS it seems it's not really practical to put multiple specs in one file because there's no way to alias a namespaced keyword without a file for it. is there any workaround for this to avoid having to split up specs into a ton of files?

robert-stuttaford15:04:04

don’t use aliases @rads

robert-stuttaford15:04:58

e.g. here i use :: for some, but i also use normal keywords directly https://github.com/robert-stuttaford/bridge/blob/master/src/bridge/spec.cljc

robert-stuttaford15:04:42

another case where some are Datomic schema, and some are to be used in e.g. fdef or manual valid? calls https://github.com/robert-stuttaford/bridge/blob/master/src/bridge/event/spec.cljc

rads15:04:50

in general I prefer to use real namespaces for the qualifier in specs, but I may have to reconsider that bias if that's the only way to work around this problem

robert-stuttaford15:04:40

there’s your problem, then 🙂

robert-stuttaford15:04:12

it’s a trade-off decision, and you’ve discovered a drawback you don’t like. time to rethink the trade-off

rads15:04:12

correct, there's no alias in CLJS

✔️ 4
rads15:04:39

I mean I would still do what I've already been doing if this wasn't a specific limitation of CLJS

rads15:04:10

but yeah, sounds like it's not possible to do it any other way

robert-stuttaford15:04:29

why can’t you just call out the spec names manually?

robert-stuttaford15:04:58

(ns specs) (s/def :something/here ) (s/def :something.nested/here )

robert-stuttaford15:04:32

the alias system is really just a convenience to prevent extra reading / typing; there’s nothing that says they have to be directly related via the ns

rads15:04:48

maybe it's worth typing out the whole thing instead of splitting up into more files

rads15:04:17

as you said, it's a matter of convenience

robert-stuttaford15:04:20

bonus: moving them around later is a LOT easier to do. :: is a sharp tool; moving things leads to non-obvious bugs, e.g. multi-method dispatches failing

rads15:04:44

can you clarify that last part? my understanding is that using :: makes you less prone to missing a defmethod

rads15:04:09

since you need to :require a namespace to refer to it with ::

robert-stuttaford15:04:46

so if you use s/def ::my-spec in ns a and then implement code that uses :a/my-spec and then move that spec to ns b, your hard-coded call no longer reaches the spec

rads15:04:21

that doesn't happen for me because I would rename the namespace that contains the spec

rads15:04:29

since they correspond to the namespaces

robert-stuttaford15:04:38

i.e. you have to be truly vigilant about always referencing them via ns require and aliases, which, as you’ve seen, comes with its own drawbacks

rads15:04:48

I've overheard that improved aliasing was being considered at some point, but it doesn't seem like it will happen any time soon

robert-stuttaford15:04:12

🙂 better to work with the tools you have, i reckon

rads15:04:50

so in summary the solution to my problem is to stop using :: and make all the keywords fully qualified. then it doesn't matter what the file is

robert-stuttaford15:04:11

or to only use :: sparingly 🙂 it is still useful!

rads15:04:10

thanks for your help

rads15:04:09

why do you use bridge.spec as the qualifier for some specs (using ::) and only bridge for others (fully qualified)?

robert-stuttaford15:04:05

they’re the generic specs; ones that ‘extend’ the clojure core with more ‘basics’ that are not specific to the app domain. i’ve had a look, and those are the only ones that got this treatment, so i may simply just type it out for them as well, to keep it consistent in the codebase.

rads15:04:01

by type it out, you mean use :bridge/ for all specs instead of ::?

robert-stuttaford15:04:32

thanks for the questions @rads - good chat - i ended up renaming that handful 🙂

rads15:04:05

awesome 🙂

jpaulorio20:04:18

Hello everyone! I’m a Clojure script beginner and I’d like to know which library should I pick to start developing React apps (browser only). After digging a little bit I encountered names like Om, Om Next, Reagent, Re-frame, etc… I thought if I asked here it could save me a lot of time figuring it out myself which one to use. Thanks in advance!

mattly20:04:11

After adding npm-deps to my clojurescript project, I’m seeing a npm ERR! 404 Not Found: @cljs-oss/module-deps@latest error on my CI build - is this a specific module the cljs compiler pulls in?

milomord20:04:50

Yes it seems required to use npm-deps, usually I just add it to package.json

milomord20:04:14

Hi @jpaulorio, Reagent is probably the simplest way to get started, but it doesn't really make any decisions about state management for you except using reagent/atoms to manage state

milomord20:04:48

The docs are pretty good for a few examples to get the idea: https://reagent-project.github.io/

milomord20:04:08

Then for bigger applications I prefer Re-frame to Om/Om Next personally, but this is really a preference. If coming from Redux I would recommend Re-frame

milomord20:04:12

Also to be clear Re-frame sits on top/around reagent similar to how a Flux/Flux-ish framework might sit next to React

gabriele20:04:23

can't get reagent 0.8.0 to work with shadow-clj, keep getting "The required namespace "react" is not available, it was required by "reagent/core.cljs""

gabriele20:04:01

should i just keep away from using 0.8.0 for now or is there a way to fix it?

maleghast21:04:12

Does anyone have a recommendation for a date-picker that plays well with Reagent?

pesterhazy21:04:41

react-datetime

pesterhazy21:04:16

1159 github stars!

pesterhazy21:04:27

Dunno, look it up?

maleghast21:04:52

I am doing now - was just wondering if you knew 🙂

dehli23:04:44

Hey you all, are there any examples of cljs test runners using regular clojure (instead of boot or lein)

dehli23:04:25

I’m having issues getting clojure to see my cljs files

dehli23:04:05

I’m using deps.edn and am able to successfully build the project with regular clojure. I was testing with lumo, but I’d like to try to use clojure instead