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
@olivergeorge is that the right version? Auditing node_modules should clarify
There are some resolution edgecases - and we did take a patch recently
Quick follow up on this. I'm seeing the same error with 1.10.866 which suggests CLJS-3293 fix doesn't help.
@felipecortezfi I’m curious why it matters
@dnolen for some reason the SmartTVs I'm running on get a bit confused and either crash or navigate to a different page
Oh ha ok
getting rid of the iframe seems to fix it
yeah, crazy stuff, sorry
@felipecortezfi figwheel uses web sockets
Probably shadow too?
oh, I thought they were invoking cljs.main too. do they not require the browser repl namespaces then? I'll try them out!
cljs.main ain’t got nothing to do with browser REPL
All that stuff can be controlled
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
It can be wrapped and overridden
More importantly it’s a pattern not a law
oh, any pointers on to how to do something like that?
I don’t know if shadow works this way - it has another way - but figwheel for sure just implements the interface
But shadow may also just solve the particular problem - I don’t know
@felipecortezfi specifically you can :browser-repl false
If it’s not being overridden to elide the preload
nice!
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?
-h shows the options
It’s a REPL specific option we should prob document
(Might be missing!)
Fell free to open issue on the site
I will! thanks!
done! https://github.com/clojure/clojurescript-site/issues/382
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.
personally, never had good experience with cljsjs
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
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
yeah the webpack minimize takes a really long time, in our build it’s 15 minutes
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
haven’t looked into it recently, the webpack replacements I tried a year ago didn’t really work
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).
I’ll check it out, thanks
our (unminified by webpack) advanced compilation output is 5mb 😅
the webpack minification shrinks it to 3.6mb
🙂
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
Tell me if it's useful for me to contribute a report somewhere (jira or ask)
it depends. if you just use e.g. react and a few other standalone libs, which don't change much, it works fine.
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
Did anybody see an error with just a message "invalid time"?
It's date-fns 😄
@olivergeorge thanks it was reported before, just fixed it now - https://github.com/clojure/clojurescript-site/issues/364
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"
}
}
@kimo that is odd. probably something related to the pdf stuff. pdfjs is known to be somewhat tricky package.
Sorry, posted the message before it was finished. I'm requiring https://www.npmjs.com/package/reactjs-pdf-reader
try creating a externs/app.txt
with just one line for __webpack_require__
pdf.js unfortunately is one of those packages that really expects you to use webpack and isn't quite happy with anything else
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))))
hmm.. created that file with no effect.
I did have some pdfjs troubles with react-pdf, but I was hoping this package would be alright. It works fine in watch mode.
hmm yeah the problem is not pdf.js
the problem is the reactjs-pdf-reader lib itself. it is packaged as a webpack debug build using eval for everything
that is extremely terrible and nobody should be doing or using that
haha
guess I'll keep looking around. somehow there's got to be a straightforward way to render pdf in cljs and/or reagent
just use pdfjs directly. really no need for a react wrapper.
Thanks! I'll look into it..
maybe this helps https://github.com/thheller/reagent-pdfjs
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.)
(As in, not part of any deps.edn
or project.clj
.
Nope.
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.
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?
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.
Fails = x and y become nan
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.
I am in the browser.
Ya, that's what I feared, thanks.
(I mean, I'm happy to use ES6's import
expression (separate from the top level import
statement.)
If clojurescript supports that?
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.
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.
self hosted cljs has its own caveats that might not make it a good fit
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
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.
I do have self-hosted cljs.
And I have a load function
(I'm, err, building a clojurescript ide in the web.)
So I already have those. 😉
I'm basically trying to set up a (super light weight) dependency manager for it.
Oh, right, my bad - by "in the browser" I meant "not self-hosted". 🤦
I thought a dynamic require "worked" for self hosted provided the load function was set up?
> Oh, right, my bad - by "in the browser" I meant "not self-hosted". Ah, okay. 🙂
OH, I think I get where you're going with this now.
At some point, I was trying some self hosted cljs stuff and I thought I had dynamic requires
I can have the load
function point to the cljs source. Or of its a compiled javascript file, just the js text directly.
Ya...I kind of feel a bit silly now. Since I'm already 'technically' dynamically requiring the user's modules...
I just never put the two and two together. Woops. Also thanks. 🙂
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?
always happy to rubber duck :thumbsup:
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 thoughI don't 'think' so, but I could easily be wrong: http://cljs.github.io/api/cljs.js/STARload-fnSTAR
It looks like you can set :source
to :js
. Although the docs here are a bit...terse...
Thanks! I thought clj->js
worked recursively. Now it works.
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.
I really appreciate your help 🙂
clj->js
does work recursively. But it doesn't convert any JS types that aren't plain arrays or objects, with a few exceptions.
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
or for interop with js libraries
You are right about that order. Did not even consider that 🙂 I thought of them as constructors, but they are functions
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
Welp, only one way to find out. 🙂
(I'll let you know if it works.)
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
I mean you are close but the .then stuff makes it look much more confusing that it needs to be
oh nevermind. I'm blind .. got confused by your variable names 😛
(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 "<https://raw.githubusercontent.com/erikbrinkman/d3-dag/main/examples/grafo.json>")
(.then draw-dag)))
maybe an attempt at making this slightly cleaner?
Wow, thank you. This is super useful.
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