Fork me on GitHub

Q1. Is there a way to share :npm-deps amongst :cljsbuild {:builds []} (using lein-cljsbuild)?


Q2. If I’m not managing the package.json with the :npm-deps option, when how can I consume the installed ./node_modules/? Do I have to provide :foreign-libs entry for them manually? (which directive should be shared again amongst the different build-ids)


Q3. Is it possible to use pnpm instead of npm? I suspect it has the same options as npm (at least the ones used by the :npm-deps support), but it only exposes the explicitely declared packages under ./node_modules, excluding the transitive deps.


Q4. Is it possible to consume :foreign-libs [{:module-type :es6 :file "src/es6/"}] when the ES6 module uses async/await? I’m getting this error:

Prompt will show when Figwheel connects to your application
[Rebel readline] Type :repl/help for online help info
ERROR: JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT8 mode or better: async function. at /Users/onetom/ line 2 : 9
ERROR: JSC_LANGUAGE_FEATURE. This language feature is only supported for ECMASCRIPT8 mode or better: async function. at /Users/onetom/ line 7 : 21
java.lang.Exception: Closure compilation failed
        at cljs.closure$report_failure.invokeStatic(closure.clj:411)
        at cljs.closure$report_failure.invoke(closure.clj:403)
        at cljs.closure$convert_js_modules.invokeStatic(closure.clj:1916)
        at cljs.closure$convert_js_modules.invoke(closure.clj:1899)
        at cljs.closure$process_js_modules.invokeStatic(closure.clj:2665)
        at cljs.closure$process_js_modules.invoke(closure.clj:2626)
        at cljs.closure$handle_js_modules.invokeStatic(closure.clj:2780)
        at cljs.closure$handle_js_modules.invoke(closure.clj:2741)
        at cljs.repl$evaluate_form.invokeStatic(repl.cljc:522)
        at cljs.repl$evaluate_form.invoke(repl.cljc:498)
BUT then this doc string is printed:
-- Docs for key :language-in --
Configure the input and output languages for the closure library. May
be :ecmascript3, ecmascript5, ecmascript5-strict, :ecmascript6-typed,
:ecmascript6-strict, :ecmascript6 or :no-transpile.

Defaults to :ecmascript3

  :language-in  :ecmascript3
while the documentation suggests there are more values possible, like :es-next


The file it complains about looks like this:

export default function BrowserContractLoader (netId) {
  return async (contractName) => {
    const jsonInterfaceUrl = [
    const response = await fetch(jsonInterfaceUrl) // eslint-disable-line no-undef
    if (response.ok) {
      return response.json()
    } else {
      throw Error(
        `Contract JSON interface doesn't exist: ${jsonInterfaceUrl}`)


@onetom that is a problem in the figwheel validation


I'll make an issue for it


the rest I'm not sure about


look at the values for the :validate-config option


i will try it again once fixed. im just getting myself reacquianted with the ecosystem after a year and i was giving figwheel a try. i was a boot user before, but now i work with a different team, so im trying to learn more mainstream tooling, so my colleagues can google for solutions themselves too


@viebel i think your were asking about core.async js interop; i would recommend staying away from this promise / async / await business, because it’s not really powerful. core.async is better but still quite low-level. we used rxjs in our recently released project ( but rxjs is in the middle of a big rehaul of their api and packaging, plus we found out that their testing story is not good at all when it comes to faking time. they provide some test scheduler, but it was only meant to be used by their own test suite primarily, so it’s not very friendly or bug-free. im looking into now and it’s very promising so far. in fact, i tried to port the function above using baconjs via the :npm-deps support and it worked immediately!

(ns figwheel-lab.core
    [baconjs :as b :refer [Bacon]]))


(-> Bacon
    (.fromPromise (js/fetch "/net/4/oax.json"))
    (.flatMap #(.fromPromise Bacon (.json %)))


btw, i mentioned this dex project, because we are contemplating to migrate it to clojurescript during its next phase of development. that’s why im looking into how to integrate cljs with the existing es6 code base


@onetom shadow-cljs is worth having a look at if you are introducing cljs to js devs and you want less friction - npm deps are driven by package.json only. About Q1 the new cljs.main -co option can merge edn files (paths separated by :) so you could share :npm-deps that way.


thanks, but im still looking into a lein based solution so far

👍 1

i had a quick look at shadow-cljs but there is not enough examples for it yet for more advanced configs


for example i do need 1 manual :foregin-lib, web3.js, because their npm package is just not usable in the browser directly


then i might need to interact with our legacy ES6 code base too


so i need a lot of control over the compilation and runtime process. we were also running mocha tests in nodejs for code which will then run in the browser and that was just really unclear how to achieve using shadow-cljs.


I would post these questions to #shadow-cljs, I am 82% sure there are answers to all the questions you asked there. Shadow has a concept of pipeline for instance so that you can write arbitrary stuff like in boot.


Shadow also allows you to compile cljs in a way so that you can require its modules from JS with require('shadow-cljs/module-name') - ES6 should not be a problem as long as Google Closure can process it. Probably there is also a sprinkle of Babel somewhere in shadow but can't recall (using it with server side node at the moment)


Don't know if it can be useful to you, but throwing it in there:


thx. good to be reminded. their guide is long 🙂

Yehonathan Sharvit04:07:09

I was able to take a big clojurescript code base and compile it as npm with shadow-cljs compile npm and expose some functions to javascript including functions that return a core.async channel

Yehonathan Sharvit04:07:26

kudos to @thheller for shadow-cljs

Yehonathan Sharvit05:07:12

by the way, my clojuscript code was compiled originally with leiningen. But this was not an issue as there is an option in shadow-cljs to use the project.clj file


@onetom FWIW in [email protected] the web3 package is now just a npm install + (:require ["web3" :as web3]) away. no special config required, it should just work.


and shadow-cljs has no issue compiling standards compliant ES6 code so it might just work out of the box


web3 works on nodejs, sure, i just couldn't consume it directly from the browser


no idea if it actually works but it now loads fine in shadow-cljs. just don't know if all functions work. they should though.


@viebel thanks for the :lein true reminder! i will definitely give shadow-cljs a second try


@onetom could you give a few more hints on the reactivex rehaul? Where did you read about it? What is planned?


Thansk! 🙂


When using secretary is there a good solid configuration for the history api, that allows for not using hashtags on the url /#/ and covers cases such as links to other sites, hashes to ids in the page or in other pages in the site?


I've used accountant in the past to get around the hashtags. Is this the sort of thing you're after?


seems pretty cool Emile, I’ll check it out. Thanks!


or is there another library that has such facilities?


I am using reagent

Mikko Harju09:07:13

What would be the best resource to get acquainted with the CLJS compiler API? I’d be interested in reading in CLJS files for static analysis purposes (looking up e.g. re-frame subs, dependencies and such) I just blindly tried the analyze-file but it needs all the dependencies to be resolved so I thought maybe I’d ask here first and then start digging in deeper myself if no answers appear 🙂


Hi all, just wanted to say thanks for trying to help me to weigh up the argument to make for clojurescript a few weeks ago. I failed, unfortunately, the "safety" of going with Angular won with the bosses.


Hopefully I can find a gig working with a clojure/cljs stack soon 🙂

🙏 3

Sad to hear and I wish you luck! I came to ClojureScript after working with a Scala backend and AngularJS 1.5 frontend... Scala was pretty nice, but Angular...


Wow. Kind of surprised that Angular won based on "safety"...


@U6GNVEWQG It's a naive evaluation, not a true assessment. False arguments at every turn but very hard to defend against on your own.


@benisrood you get all my empathy of needing to suffer with angular. The angular 6x is a mess, it's been a mess since 2x. Luckily I was able to convince my boss to stop using it. I would have quit if he hadn't 🙂. "Safety" with angular is so naive judgement. (typescript is still relatively nice, but you can use typescript for every other framework as well)

💯 2

it was also a mess with 1.X as well 😂

👍 2

@onetom the guide on how to use CLJS with webpack to manage your npm deps was just recently published


Thanks! Although one of the main reasons for exploring Clojure in my current company is to get away from the JS world as much as possible and webpack is one of the many reasons why we don't like the JS world


I see it's recommending yarn. We also get away from yarn and use instead.


It generates a ./node_modules which only expose the explicitly declared dependencies and none of the transitive ones, making it impossible to use a module which you haven't explicitly decided about its version. It also generates a shrinkwrap.yml which contains package hashes. This way the node dependency installation is really reproducible, just like in NixOS. In fact, you can even use this shrinkwrap.yml directly with the Nix package manager and install them without pnpm being installed. (disclaimer: my colleague wrote this nix tool)


@mikko I would ask questions in #cljs-dev for now


I’m trying to use :npm-deps to pull in a library that ends up using d3, and when compiling, am getting the errors:

ERROR: JSC_PARSE_ERROR. Parse error. 'as' expected at /Users/thomas/ustudio/stats-ingest/stats-dashboard-ui/node_modules/d3-transition/src/transition/attr.js line 2 : 17
ERROR: JSC_PARSE_ERROR. Parse error. 'as' expected at /Users/thomas/ustudio/stats-ingest/stats-dashboard-ui/node_modules/d3-transition/src/transition/attrTween.js line 1 : 17
They seem to be related to this PR: which, as far as I can tell, should be in the latest closure-compiler release. I tried explicitly setting :language-in (the PR calls out different validations for different language modes), but is something else used for resolving the input language for npm deps?


my deps:

[org.clojure/clojure "1.9.0"]
[org.clojure/clojurescript "1.10.238"]


is ns a macro or special form? When I look up ns in CLJS API it says that it's special form. Is there a list of CLJS special forms just as there is one at CLJ website? I found this but it doesn't say anything about ns.




in CLJ its a macro in CLJS its a special form. I guess the difference is not mentioned since it behaves the same.


@jacek.schae A first-order list of the special forms can be obtained by doing (source special-symbol?)


anybody know how to PR Link on the Quick Start is broken:


(link to “standalone ClojureScript JAR”)


@elliot fixing, no need for the pR


@elliot should be fixed now