clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
Oliver George 2021-05-20T00:05:07.060100Z

I'm trying the webpack2 guide and struggling to replicate import AsyncSelect from 'react-select/async';

(ns metcalf3.widget.select
  (:require ["react-select/async" :as AsyncSelect]
No such namespace: react-select/async, could not locate react_select_SLASH_async.cljs, react_select_SLASH_async.cljc, or JavaScript source providing "react-select/async" (Please check that namespaces with dashes use underscores in the ClojureScript file name) in file /Users/olivergeorge/repos/metcalf/frontend/src/cljs/metcalf3/widget/select.cljs 
% cat yarn.lock | grep react-select  
react-select@^3.0.4:
  resolved "<https://registry.npmjs.org/react-select/-/react-select-3.0.4.tgz>"

% ls -l node_modules/react-select/async 
drwxr-xr-x  9 olivergeorge  staff  288 May 20 10:01 dist
-rw-r--r--  1 olivergeorge  staff  298 May 20 09:23 package.json

dnolen 2021-05-20T00:41:59.061800Z

@olivergeorge is that the right version? Auditing node_modules should clarify

dnolen 2021-05-20T00:44:14.062700Z

There are some resolution edgecases - and we did take a patch recently

Oliver George 2021-05-22T04:14:23.193900Z

Quick follow up on this. I'm seeing the same error with 1.10.866 which suggests CLJS-3293 fix doesn't help.

dnolen 2021-05-20T00:45:14.063200Z

@felipecortezfi I’m curious why it matters

Felipe 2021-05-20T00:47:01.064400Z

@dnolen for some reason the SmartTVs I'm running on get a bit confused and either crash or navigate to a different page

dnolen 2021-05-20T00:47:19.064800Z

Oh ha ok

Felipe 2021-05-20T00:47:22.064900Z

getting rid of the iframe seems to fix it

Felipe 2021-05-20T00:47:35.065300Z

yeah, crazy stuff, sorry

dnolen 2021-05-20T00:47:56.065900Z

@felipecortezfi figwheel uses web sockets

dnolen 2021-05-20T00:48:07.066300Z

Probably shadow too?

Felipe 2021-05-20T00:49:58.067600Z

oh, I thought they were invoking cljs.main too. do they not require the browser repl namespaces then? I'll try them out!

dnolen 2021-05-20T00:50:46.068800Z

cljs.main ain’t got nothing to do with browser REPL

dnolen 2021-05-20T00:50:58.069200Z

All that stuff can be controlled

Felipe 2021-05-20T00:54:07.070200Z

oh, I thought you had to set --repl-env to either browser or node, and setting it to browser would generate that browser.repl.preload line

dnolen 2021-05-20T00:54:33.070700Z

It can be wrapped and overridden

dnolen 2021-05-20T00:54:47.071200Z

More importantly it’s a pattern not a law

Felipe 2021-05-20T00:55:26.072300Z

oh, any pointers on to how to do something like that?

dnolen 2021-05-20T00:55:53.073100Z

I don’t know if shadow works this way - it has another way - but figwheel for sure just implements the interface

dnolen 2021-05-20T00:56:27.073900Z

But shadow may also just solve the particular problem - I don’t know

dnolen 2021-05-20T00:58:15.075700Z

@felipecortezfi specifically you can :browser-repl false

dnolen 2021-05-20T00:58:38.076400Z

If it’s not being overridden to elide the preload

Felipe 2021-05-20T00:59:18.076600Z

nice!

Felipe 2021-05-20T01:05:47.078100Z

clj -M --main cljs.main --compile-opts '{:browser-repl false}' works! thanks! but I thought https://clojurescript.org/reference/compiler-options was comprehensive. should I go to the source code to find out about other options or is there another way?

dnolen 2021-05-20T01:06:34.078800Z

-h shows the options

dnolen 2021-05-20T01:07:02.079500Z

It’s a REPL specific option we should prob document

dnolen 2021-05-20T01:07:26.080100Z

(Might be missing!)

dnolen 2021-05-20T01:07:57.080700Z

Fell free to open issue on the site

Felipe 2021-05-20T01:08:53.080900Z

I will! thanks!

Felipe 2021-05-20T01:22:52.081200Z

done! https://github.com/clojure/clojurescript-site/issues/382

Jacob Rosenzweig 2021-05-20T03:14:25.083100Z

Does cljsjs tend to "just work" well enough? I know a lot of platforms that promise to port over libraries but they usually fail because of language differences. JS code structure vaguely resembles Lisp wrt most logic being exported as dynamically typed functions.

Aron 2021-05-20T03:23:54.083400Z

personally, never had good experience with cljsjs

Oliver George 2021-05-20T04:03:43.085100Z

Looks like the webpack guide is written for webpack-cli v3... running against v4.7 seems to require tweaks to the args shown in the guide (relative paths, also -o seems to want a dir). Here's what you get following the guide and repeating the webpack step manually (for nicely formatted error output)...

olivergeorge@Condense-iMac webpack-repros % npx webpack out/index.js -o out/main.js --mode=development
asset main.js 662 bytes [compared for emit] (name: main)

ERROR in main
Module not found: Error: Can't resolve 'out/index.js' in '/Users/olivergeorge/repos/webpack-repros'
Did you mean './out/index.js'?
Requests that should resolve in the current directory need to start with './'.
Requests that start with a name are treated as module requests and resolve within module directories (node_modules).
If changing the source code is not an option there is also a resolve options called 'preferRelative' which tries to resolve these kind of requests in the current directory too.
resolve 'out/index.js' in '/Users/olivergeorge/repos/webpack-repros'
  Parsed request is a module
  using description file: /Users/olivergeorge/repos/webpack-repros/package.json (relative path: .)
    Field 'browser' doesn't contain a valid alias configuration
    resolve as module
      looking for modules in /Users/olivergeorge/repos/webpack-repros/node_modules
        /Users/olivergeorge/repos/webpack-repros/node_modules/out doesn't exist
      /Users/olivergeorge/repos/node_modules doesn't exist or is not a directory
      /Users/olivergeorge/node_modules doesn't exist or is not a directory
      /Users/node_modules doesn't exist or is not a directory
      /node_modules doesn't exist or is not a directory

webpack 5.37.1 compiled with 1 error in 42 ms

Oliver George 2021-05-20T04:06:48.085700Z

A few tweaks seems enough to get things going... before: npx webpack out/index.js -o out/main.js --mode=development after: npx webpack ./out/index.js -o out --mode=development

tatut 2021-05-20T04:15:45.085900Z

yeah the webpack minimize takes a really long time, in our build it’s 15 minutes

tatut 2021-05-20T04:16:24.086100Z

it’s so bad that we don’t do it for each autodeloy from master to dev env, but only for release builds… I haven’t found a solution to it yet

tatut 2021-05-20T04:17:48.086300Z

haven’t looked into it recently, the webpack replacements I tried a year ago didn’t really work

Oliver George 2021-05-20T04:23:41.086500Z

Thanks. Sounds like I'm not the only one then. The gist associated with that question has some commented out terserOptions which you might like to try (no promises).

tatut 2021-05-20T04:25:52.086700Z

I’ll check it out, thanks

tatut 2021-05-20T04:26:55.086900Z

our (unminified by webpack) advanced compilation output is 5mb 😅

tatut 2021-05-20T04:27:55.087100Z

the webpack minification shrinks it to 3.6mb

Oliver George 2021-05-20T04:28:45.087300Z

🙂

Oliver George 2021-05-20T04:33:10.087500Z

Yes. I've done a minimal repro and it seems to be easy to reproduce with current versions of react-select. https://github.com/olivergeorge/webpack-repros/commit/07b38fb5ca1622d799620f4bae9c2dcdda2c7bd2 Error is

No such namespace: react-select/async, could not locate react_select_SLASH_async.cljs, react_select_SLASH_async.cljc, or JavaScript source providing "async" (Please check that namespaces with dashes use underscores in the ClojureScript file name) in file /Users/olivergeorge/repos/webpack-repros/src/hello_bundler/core.cljs

Oliver George 2021-05-20T04:33:41.087700Z

Tell me if it's useful for me to contribute a report somewhere (jira or ask)

2021-05-20T06:08:27.088Z

it depends. if you just use e.g. react and a few other standalone libs, which don't change much, it works fine.

2021-05-20T06:09:40.088200Z

it doesn't 'scale' well, but I guess a lot of ppl don't need it to. it's hard to say from the clojure survey exactly, but I think cljsjs is not going away any time soon

Karol Wójcik 2021-05-20T09:31:31.088900Z

Did anybody see an error with just a message "invalid time"?

Karol Wójcik 2021-05-20T09:41:47.089100Z

It's date-fns 😄

dnolen 2021-05-20T10:21:08.089600Z

@olivergeorge thanks it was reported before, just fixed it now - https://github.com/clojure/clojurescript-site/issues/364

👍 1
km 2021-05-20T15:43:30.099800Z

Hey Clojurians. Having some trouble compiling a release. My build succeeds with shadow-cljs release app, but the browser reports Uncaught ReferenceError: __webpack_require__ is not defined. Any ideas? shadow-cljs.edn:

{:dependencies
 [[reagent "0.10.0"]
  [re-frame "1.2.0"]
  [json-html "0.3.5"]]
 :source-paths ["src"]
 :dev-http {8081 "public"}
 :builds
 {:app {:target :browser
        :modules
        {:app {:entries [kimok.example]}}}}}
src/example.cljs:
(ns kimok.example
  (:require
   [reagent.core :as reagent :refer [atom with-let]]
   [reagent.dom :as rdom]
   ["reactjs-pdf-reader" :as pdf]))
(defn app []
  [:&gt; pdf/PDFReader {:url "pdf/test.pdf" :showAllPage true}])
(rdom/render [app] (.getElementById js/document "app"))
package.json:
{
  "dependencies": {
    "react": "16.13.0",
    "react-dom": "16.13.0",
    "reactjs-pdf-reader": "^1.0.12"
  },
  "devDependencies": {
    "shadow-cljs": "^2.12.6"
  }
}

thheller 2021-05-20T15:46:26.100300Z

@kimo that is odd. probably something related to the pdf stuff. pdfjs is known to be somewhat tricky package.

km 2021-05-20T15:50:25.100800Z

Sorry, posted the message before it was finished. I'm requiring https://www.npmjs.com/package/reactjs-pdf-reader

thheller 2021-05-20T15:51:32.101100Z

try creating a externs/app.txt with just one line for __webpack_require__

thheller 2021-05-20T15:51:55.101300Z

pdf.js unfortunately is one of those packages that really expects you to use webpack and isn't quite happy with anything else

❤️ 1
Jakob Durstberger 2021-05-20T15:54:24.102400Z

js-&gt;clj doesn’t convert sets by default, so theheller pointend me towards extend-protocol IEncodeClojure Does this implementation seem reasonable?

(extend-protocol IEncodeClojure js/Set
                   (-js-&gt;clj [js-set options]
                     (into #{} (map js-&gt;clj js-set))))

km 2021-05-20T15:54:44.102500Z

hmm.. created that file with no effect.

km 2021-05-20T16:03:18.102700Z

I did have some pdfjs troubles with react-pdf, but I was hoping this package would be alright. It works fine in watch mode.

thheller 2021-05-20T16:05:45.102900Z

hmm yeah the problem is not pdf.js

thheller 2021-05-20T16:06:41.103100Z

the problem is the reactjs-pdf-reader lib itself. it is packaged as a webpack debug build using eval for everything

thheller 2021-05-20T16:06:42.103300Z

https://unpkg.com/reactjs-pdf-reader@1.0.12/lib/app.js

thheller 2021-05-20T16:07:18.103500Z

that is extremely terrible and nobody should be doing or using that

km 2021-05-20T16:07:23.103700Z

haha

km 2021-05-20T16:08:49.103900Z

guess I'll keep looking around. somehow there's got to be a straightforward way to render pdf in cljs and/or reagent

thheller 2021-05-20T16:10:36.104100Z

just use pdfjs directly. really no need for a react wrapper.

km 2021-05-20T16:18:32.104300Z

Thanks! I'll look into it..

thheller 2021-05-20T17:07:05.104700Z

maybe this helps https://github.com/thheller/reagent-pdfjs

👏 1
🔥 3
2021-05-20T18:29:39.106400Z

Is there any way to do a dynamic require in clojurescript? (Possibly to require a javascript module that was downloaded after the project was built.)

2021-05-20T18:30:01.106900Z

(As in, not part of any deps.edn or project.clj .

Karol Wójcik 2021-05-20T18:43:04.107Z

Nope.

Karol Wójcik 2021-05-20T18:44:05.107300Z

There is no notion of dynamic require in ClojureScript. If script is already downloaded and eval'ed then you can access it's properties via js/<something> interop.

Endre Bakken Stovner 2021-05-20T18:45:51.109Z

I have the following two code snippets: https://gist.github.com/endrebak/96a9abeefcb3ff827ae717076161c182 One in JS which works and one seemingly identical in Cljs which fails. The output is written in a comment at the bottom. Can anyone see any differences? Or have any hints about how to debug?

Endre Bakken Stovner 2021-05-21T18:08:53.174800Z

Thanks! Appreciate all the help. Also, I've realized that I can't get by blindly trying stuff so I've started reading about React, Cljs and D3.

Endre Bakken Stovner 2021-05-20T18:47:29.109300Z

Fails = x and y become nan

p-himik 2021-05-20T18:50:53.109400Z

There is dynamic require if you're on Node. Or at least, not in the browser. There is module splitting in CLJS, so it might be possible to play around with the module loader to have a truly dynamic loading where you have no information about the module in advance. If all else fails, you can always just use the good old "add &lt;script&gt; to the document in run time" technique.

2021-05-20T18:54:54.109600Z

I am in the browser.

2021-05-20T18:55:02.109800Z

Ya, that's what I feared, thanks.

2021-05-20T18:55:33.110Z

(I mean, I'm happy to use ES6's import expression (separate from the top level import statement.)

2021-05-20T18:55:39.110200Z

If clojurescript supports that?

p-himik 2021-05-20T18:59:56.110400Z

Closure compiler supports dynamic imports fully since 20210505. Shadow-cljs has shadow.esm/dynamic-import. How much of a trouble to use all that - no clue. Might be worth asking in #shadow-cljs if you use it.

phronmophobic 2021-05-20T19:02:05.110700Z

It should be possible if you have self-hosted cljs (see https://cljs.github.io/api/cljs.js/#eval). You would have to provide a load function that knew how to obtain the cljs source for the namespace you were requiring.

phronmophobic 2021-05-20T19:02:35.110900Z

self hosted cljs has its own caveats that might not make it a good fit

p-himik 2021-05-20T19:03:38.111100Z

The code blocks are not identical in at least two ways: 1. Order of some functions is different. I'm not familiar with D3 to tell whether it's important or not 2. You're using CLJS data structures where JS ones are used in the JS code sample

p-himik 2021-05-20T19:04:13.111300Z

Take a close look at node-size. Also, don't use clj-&gt;js when the data structure is known in advance. Just use the #js reader tag.

2021-05-20T19:05:39.111500Z

I do have self-hosted cljs.

2021-05-20T19:05:53.111700Z

And I have a load function

2021-05-20T19:06:04.111900Z

(I'm, err, building a clojurescript ide in the web.)

1
🎉 1
2021-05-20T19:06:15.112100Z

So I already have those. 😉

2021-05-20T19:06:43.112300Z

I'm basically trying to set up a (super light weight) dependency manager for it.

p-himik 2021-05-20T19:07:04.112500Z

Oh, right, my bad - by "in the browser" I meant "not self-hosted". 🤦

phronmophobic 2021-05-20T19:07:43.112700Z

I thought a dynamic require "worked" for self hosted provided the load function was set up?

2021-05-20T19:08:48.113100Z

> Oh, right, my bad - by "in the browser" I meant "not self-hosted". Ah, okay. 🙂

2021-05-20T19:10:06.113300Z

OH, I think I get where you're going with this now.

phronmophobic 2021-05-20T19:10:39.113500Z

At some point, I was trying some self hosted cljs stuff and I thought I had dynamic requires

2021-05-20T19:10:53.113700Z

I can have the load function point to the cljs source. Or of its a compiled javascript file, just the js text directly.

2021-05-20T19:12:01.113900Z

Ya...I kind of feel a bit silly now. Since I'm already 'technically' dynamically requiring the user's modules...

2021-05-20T19:12:23.114100Z

I just never put the two and two together. Woops. Also thanks. 🙂

phronmophobic 2021-05-20T19:12:39.114300Z

I thought the load would function would need to provide the cljs source (not just the compiled js) so that it could analyze the code and update its internal compiler state, but maybe the js would be enough?

phronmophobic 2021-05-20T19:13:28.114500Z

always happy to rubber duck :thumbsup:

Endre Bakken Stovner 2021-05-20T19:15:09.114800Z

Thanks! 1( I can't see which differ in order. 2( Fixed:

(.nodeSize #js [60 60])

node-size #js (fn [] #js [base base])
I cannot see any more cljs data structures I use. 3( node-size is now changed to be all js. Is there more wrong with it? 4( Noted. Still fails though

2021-05-20T19:20:10.115100Z

I don't 'think' so, but I could easily be wrong: http://cljs.github.io/api/cljs.js/STARload-fnSTAR

2021-05-20T19:20:44.115300Z

It looks like you can set :source to :js. Although the docs here are a bit...terse...

Endre Bakken Stovner 2021-05-20T19:21:46.115500Z

Thanks! I thought clj-&gt;js worked recursively. Now it works.

p-himik 2021-05-20T19:21:51.115700Z

You don't need #js in front of the function. On the order - compare when you call d3.layeringSimplex and d3.sugiyama relative to each other between CLJS and JS code blocks.

👍 1
Endre Bakken Stovner 2021-05-20T19:21:56.115900Z

I really appreciate your help 🙂

👍 1
p-himik 2021-05-20T19:22:20.116100Z

clj-&gt;js does work recursively. But it doesn't convert any JS types that aren't plain arrays or objects, with a few exceptions.

phronmophobic 2021-05-20T19:22:20.116300Z

I think that's if the namespace already been precompiled:

:cache      - optional, if a :clj namespace has been precompiled to :js, can
              give an analysis cache for faster loads.
:source-map - optional, if a :clj namespace has been precompiled to :js, can
              give a V3 source map JSON

phronmophobic 2021-05-20T19:22:48.116600Z

or for interop with js libraries

Endre Bakken Stovner 2021-05-20T19:24:09.116900Z

You are right about that order. Did not even consider that 🙂 I thought of them as constructors, but they are functions

phronmophobic 2021-05-20T19:24:47.117100Z

but I'm not 100% sure. Maybe it's the same thing if the namespace doesn't have any macros, but I'm not sure how it might work otherwise

2021-05-20T19:32:36.117300Z

Welp, only one way to find out. 🙂

2021-05-20T19:32:45.117500Z

(I'll let you know if it works.)

👍 1
thheller 2021-05-20T19:40:39.117900Z

This is not identical. you are missing the all important async function and the await. I already gave you the solution yesterday. figure out how to get out of the async and then build from there. maybe first try rewriting the JS example without async/await

thheller 2021-05-20T19:41:18.118100Z

I mean you are close but the .then stuff makes it look much more confusing that it needs to be

thheller 2021-05-20T19:42:23.118300Z

oh nevermind. I'm blind .. got confused by your variable names 😛

thheller 2021-05-20T19:47:08.118500Z

(defn draw-dag [dag-data]
  (let [reader (d3-dag/dagStratify)
        dag (reader dag-data)
        node-radius 20
        padding 1.5
        base (* node-radius padding 2)
        node-size #js (fn [] #js [base base])
        layout (-&gt;
                 (d3-dag/sugiyama)
                 (.nodeSize #js [60 60])
                 (.layering (d3-dag/layeringSimplex))
                 (.decross (d3-dag/decrossOpt))
                 (.coord (d3-dag/coordQuad))
                 (.nodeSize node-size))

        obj (layout dag)]

    (js/console.log obj)))

(defn load-dag []
  (-&gt; (d3/json "<https://raw.githubusercontent.com/erikbrinkman/d3-dag/main/examples/grafo.json>")
      (.then draw-dag)))

thheller 2021-05-20T19:47:23.118700Z

maybe an attempt at making this slightly cleaner?

km 2021-05-20T21:00:29.119Z

Wow, thank you. This is super useful.

👍 1
2021-05-20T22:41:12.120800Z

Hello! Can I customize lein figwheel repl options somewhow (actually I want custom prompt), like I can do for lein repl ? Seems that :repl-options {:prompt ...}} does not affect at all