Fork me on GitHub
#clojurescript
<
2021-05-20
>
Oliver George00:05:07

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  
[email protected]^3.0.4:
  resolved ""

% 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

dnolen00:05:59

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

Oliver George04:05:10

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 George04:05:41

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

dnolen00:05:14

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

Oliver George04:05:23

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

dnolen00:05:14

@felipecortezfi I’m curious why it matters

Felipe00:05:01

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

Felipe00:05:22

getting rid of the iframe seems to fix it

Felipe00:05:35

yeah, crazy stuff, sorry

dnolen00:05:56

@felipecortezfi figwheel uses web sockets

dnolen00:05:07

Probably shadow too?

Felipe00:05:58

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

dnolen00:05:46

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

dnolen00:05:58

All that stuff can be controlled

Felipe00:05:07

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

dnolen00:05:33

It can be wrapped and overridden

dnolen00:05:47

More importantly it’s a pattern not a law

Felipe00:05:26

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

dnolen00:05:53

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

dnolen00:05:27

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

dnolen00:05:15

@felipecortezfi specifically you can :browser-repl false

dnolen00:05:38

If it’s not being overridden to elide the preload

Felipe01:05:47

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?

dnolen01:05:34

-h shows the options

dnolen01:05:02

It’s a REPL specific option we should prob document

dnolen01:05:26

(Might be missing!)

dnolen01:05:57

Fell free to open issue on the site

Felipe01:05:53

I will! thanks!

Jacob Rosenzweig03:05:25

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.

henryw37406:05:27

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

henryw37406:05:40

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

Aron03:05:54

personally, never had good experience with cljsjs

Oliver George04:05:43

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)...

[email protected] 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 George04:05:48

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

Karol Wójcik09:05:31

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

Karol Wójcik09:05:47

It's date-fns 😄

dnolen10:05:08

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

👍 2
km15:05:30

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 []
  [:> 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"
  }
}

thheller15:05:26

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

km15:05:25

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

thheller15:05:32

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

thheller15:05:55

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

❤️ 2
km15:05:44

hmm.. created that file with no effect.

km16:05:18

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

thheller16:05:45

hmm yeah the problem is not pdf.js

thheller16:05:41

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

thheller16:05:18

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

km16:05:49

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

thheller16:05:36

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

km16:05:32

Thanks! I'll look into it..

km21:05:29

Wow, thank you. This is super useful.

👍 2
Jakob Durstberger15:05:24

js->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->clj [js-set options]
                     (into #{} (map js->clj js-set))))

leif18:05:39

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.)

Karol Wójcik18:05:05

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.

p-himik18:05:53

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 <script> to the document in run time" technique.

leif18:05:54

I am in the browser.

leif18:05:02

Ya, that's what I feared, thanks.

leif18:05:33

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

leif18:05:39

If clojurescript supports that?

p-himik18:05:56

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.

phronmophobic19:05:05

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.

phronmophobic19:05:35

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

leif19:05:39

I do have self-hosted cljs.

leif19:05:53

And I have a load function

leif19:05:04

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

🎉 2
clojure-spin 2
leif19:05:15

So I already have those. 😉

leif19:05:43

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

p-himik19:05:04

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

phronmophobic19:05:43

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

leif19:05:48

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

leif19:05:06

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

phronmophobic19:05:39

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

leif19:05:53

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

leif19:05:01

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

leif19:05:23

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

phronmophobic19:05:39

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?

phronmophobic19:05:28

always happy to rubber duck :thumbsup:

leif19:05:10

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

leif19:05:44

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

phronmophobic19:05:20

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

phronmophobic19:05:48

or for interop with js libraries

phronmophobic19:05:47

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

leif19:05:36

Welp, only one way to find out. 🙂

leif19:05:45

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

👍 2
leif00:05:09

@U7RJTCH6J Welp, so I can get it to evaluate javascript just fine, although if that javascript is a compiled webpack thing, then it complains. So shrug. 🙂

leif00:05:37

Oh wait, that's just because the webpack bundle had co-dependencies. Never mind.

leif18:05:01

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

Endre Bakken Stovner18:05:51

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?

thheller19:05:39

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

thheller19:05:18

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

thheller19:05:23

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

thheller19:05:08

(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 (->
                 (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 []
  (-> (d3/json "")
      (.then draw-dag)))

thheller19:05:23

maybe an attempt at making this slightly cleaner?

Endre Bakken Stovner18:05:53

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 Stovner18:05:29

Fails = x and y become nan

p-himik19:05:38

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-himik19:05:13

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

Endre Bakken Stovner19:05:09

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

Endre Bakken Stovner19:05:46

Thanks! I thought clj->js worked recursively. Now it works.

p-himik19:05:51

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.

👍 2
Endre Bakken Stovner19:05:56

I really appreciate your help 🙂

👍 2
p-himik19:05:20

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

Endre Bakken Stovner19:05:09

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

ivana22:05:12

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