Fork me on GitHub
#clojurescript
<
2018-02-27
>
qq00:02:46

Hello, I am looking for ways to compile my cljs as a node package. As reference, following the datascript approach https://github.com/tonsky/datascript/tree/master/release-js , which builds the bare js version and then add the prefix and suffix, and append them at the top and bottom of the the bare js content. Just curious is any other aprroach which may be more straightforward?

zentrope01:02:44

Alas, I use Safari. Ah, well.

souenzzo15:02:52

testing in my "small" project but there is a changelog?

souenzzo15:02:36

no problems in my re-frame project 🙂

raymcdermott13:02:23

I’m hoping that you folks can help me …. is there an idiomatic approach to integrate with JS libs that use ES7 async/await from CLJS?

thheller13:02:06

@raymcdermott async/await is just syntax sugar around promises so you either .then something you get from JS or hand it a promise

thheller13:02:33

do you have an example of the lib you want to use?

jmckitrick13:02:01

Hi all. I’m working on the first cljs app for our company, and I’ve run into a roadblock. I need to use 2 react components from npm. They currently do not have wrappers in cljsjs, and both online extern-generating tools have errored out saying ‘namespace not found’. I only know enough about external js libraries to have imported a few before that didn’t need any extra work. But I’m stuck now. Any suggestions?

raymcdermott13:02:51

@thheller true that it’s sugar over promise, so is your point that we can just ignore the fact that the libs use async/await?

raymcdermott13:02:00

here is one example

raymcdermott13:02:23

and yes indeed the exposed values are Promise

raymcdermott14:02:42

I’ll get my coat

wilkerlucio14:02:08

@raymcdermott you can write a macro that solves that, I was trying to find here, but once I wrote a <!p that works just like <! but on JS promises (still need to be inside go blocks)

wilkerlucio14:02:48

(ns common-js.async
  (:require [clojure.core.async :as async]))

(defmacro go-catch [& body]
  `(cljs.core.async.macros/go
     (try
       [email protected]
       (catch :default e e))))

#?(:cljs
  (defn promise->chan [p]
    (let [c (async/promise-chan)]
      (.then p
             #(async/put! c {:success %})
             #(async/put! c {:error %}))
      c)))

#?(:cljs
  (defn consumer-pair [resp]
    (if (contains? resp :error)
      (throw (:error resp))
      (:success resp))))

(defmacro <!p [promise]
  `(consumer-pair (cljs.core.async/<! (promise->chan ~promise))))

leonoel14:02:07

@wilkerlucio remember everything is throwable in javascript, even undefined, so your either implementation is brittle

wilkerlucio14:02:37

@leonoel not sure what you mean, if you look at promise->chan, the err will only be present when the promise fails, otherwise will be nil, so the if on consume-pair will not throw, did you see something else I'm missing?

leonoel14:02:28

if an evil library returns a failed promise with a falsey value as error, your code will not propagate failure

wilkerlucio14:02:03

then the library is doing it wrong doesn't it? I never had a case where a promisse error is not an actual error object, that seems a wrong implementation to me

leonoel14:02:45

I agree it would be unexpected, but it's allowed by both the language and the promise semantics, so nothing says it would be wrong

wilkerlucio14:02:09

@leonoel ok, I can agree with that, updated it, what you think?

wilkerlucio14:02:17

thanks for pointing it out

dnolen15:02:58

@jmckitrick make a foreign dep of those and try externs inference - also shadow-cljs appears to have a smoother story for integrating NPM stuff (`:npm-deps` is cool but requires a certain level of NPM semantics understanding / Closure Compiler expertise)

souenzzo15:02:19

I place all my code in src dir, some like this src/app/ (cljc), src/client/ (cljs), src/server/ (clj) My cljs build is really slow, due it load all (not required's) namespaces from src/server. There is how cljs build load just the required clojure or i will need to split in src-clj/`src-cljs`/`src-cljc`?

wilkerlucio16:02:09

shadow-cljs does a good there, it only loads things your code actually needs

souenzzo17:02:55

I'm actually with figwhell for dev and cljsbuild to production shadow-cljs will replace just cljsbuild, right?

wilkerlucio18:02:10

no, shadow-cljs is for dev too, so no figwheel or cljsbuild

erwinrooijakkers16:02:38

I read in the ClojureScript cljs.test code:

A fixture is a map of one or two functions that run code before and
   after tests.  It looks like this:
   {:before (fn []
              Perform setup, establish bindings, whatever.
              )
    :after (fn []
             Tear-down / clean-up code here.
             )}

erwinrooijakkers16:02:46

How can we add bindings?

erwinrooijakkers16:02:54

E.g., is it possible to add bindings around an fn?

(defn my-fixture [f]
  (binding [*my-binding* 1]
      (f)))
What would be the equivalant using the map with :before and :after?

dnolen16:02:33

binding doesn’t work for async tests

erwinrooijakkers16:02:10

I am indeed trying to run an async test

rgm17:02:38

I'm struggling quite a bit with getting the cljs compiler, DCE, and node modules ... I'm hoping someone can straighten me out, because I suspect my expectations are completely wrong... here's a minimal lein-cljsbuild test I'm trying https://gist.github.com/rgm/da7c0e814fb7482f3aa9741076eab34b ...

rgm17:02:02

I put in the commented-out react-router bits just to see what happens to code I don't use ... I'd expect the size of app.min.js not to change at all. (BTW node app.min.js will spit out a hello-world div as expected).

rgm17:02:23

(btw is there a canonical doc somewhere for doing this with lein? The feature sounds exciting but with so much of the knowledge about it being folkloric it's a bit discouraging).

dnolen17:02:10

@rgm using Node modules and passing them through Closure is still an advanced topic

dnolen17:02:44

also an alpha feature subject to change - so not a ton of documentation

dnolen17:02:14

if you want to try this stuff out - you definitely need to buckle down 🙂

dnolen17:02:24

otherwise build a foreign lib, or try shadow-cljs

rgm17:02:57

ok, so ignoring my last little bit of sadness, is this kinda the gist of it?

dnolen17:02:17

yes looks ok

dnolen17:02:39

but DCE isn’t magic - if the JS library does something overly dynamic, it’s not going to work

dnolen17:02:58

many libs don’t, many libs do - so you just have to try and see

rgm17:02:10

ok, thanks... thought I was doing something wrong.

dnolen17:02:29

no DCE works only if Google Closure can prove something isn’t needed

dnolen17:02:00

there’s many dynamic patterns where can’t prove this

dnolen17:02:28

ClojureScript generates JS specifically to ensure it can be done

dnolen17:02:46

but you still need to take care in some cases with that help

rgm17:02:46

so philosophically it seems like I'm good on my build plumbing, and I'm best to move my exploration/experimentation to understanding the patterns around JS packaging?

dnolen17:02:35

I think so

rgm17:02:46

cool, thanks muchly.

rgm17:02:17

another thing (of the many, sadly) that I'm fuzzy on: removing cljsjs/react etc. from the project :dependencies doesn't seem to cause grief around externs ... is this being inferred?

juhoteperi17:02:40

@rgm React uses some dynamic properties, so externs are required (but it has been a few months since I last tested this, don't know about latest React)

juhoteperi17:02:30

But you can require the cljsjs packages in the project, node_modules will have precedence over cljsjs foreign-libs so the cljsjs JS shouldn't be included in the build

rgm17:02:41

mm, so maybe I just had some dumb luck there.

juhoteperi17:02:54

This requires that cljs namespaces only require react react-dom, not old cljsjs.* names

juhoteperi17:02:23

IIRC the dynamic properties are related to DOM event props, so if you don't need to access those, everything might work

jmckitrick19:02:29

Is there anything special required to use JS libraries in ES6 syntax? I’m seeing errors when loading JS files that are fine outside of cljs

justinlee19:02:10

how are you loading them?

jmckitrick21:02:49

I’m trying a few approaches. Linking them in the html page right now.

jmckitrick21:02:06

But I’m also trying to generate externs and treat them as foreign libraries in src.

jmckitrick21:02:34

I’m not sure if my method is broken or if there’s something unusual about the libraries, since both fail to generate externs when using the 2 online tools for cljsjs

justinlee21:02:48

aside from using shadow-cljs, the way i had the most luck with was to find the UMD build of the library and include it via foreign-libs, then use cljs-oops to access objects and properties and forget about externs

pesterhazy23:02:58

@jmckitrick often you need to access libraries like this: (.-default libFromNPM)