Fork me on GitHub
#clojurescript
<
2020-05-21
>
rgm04:05:03

I’m messing around with three.js and the new bundle target. I can get (require '[three]) to work through figwheel + webpack, with /node_modules/three and all’s well … I have a three ns and can call (three/AmbientLight. 0x202020) etc. Where I’m hoping for a little guidance is how to reach into other stuff in the node module.

rgm04:05:21

Eg. there’s a collada/dae model loader class, and I can’t quite figure out how to phrase my (require ,,,) to get at it, eg. https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_collada.html#L21-L23

rgm04:05:52

(The file is sitting at /projectroot/node_modules/three/examples/jsm/loaders/ColladaLoader.js … I can cat it, but … how do I tell cljs about it in a require?)

didibus04:05:54

How would you require it in NodeJS?

didibus04:05:32

I think your example is an ES6 import. The bundle target will generate NodeJS require from the Clojure require macro. I'm still new to all of it, so that's all I can think of. But basically it be you need to follow what NodeJS would do.

didibus04:05:15

And the you can (require 'three-collada-loader)

rgm04:05:07

Hm. Yep. That’d probably do it. :man-facepalming:

rgm04:05:25

Weird: no references to that in the official docs.

rgm04:05:01

And good thought: guess I can just experiment and watch what shows up in the npm_deps.js after cljs compile but before it goes into webpack

didibus04:05:10

Ya, I wonder if you can do (require '["./example/jsm/..." :as collada-loader])

thheller10:05:51

shadow-cljs supports that but the feature was rejected for CLJS so its non-standard

didibus04:05:56

Oh I think I remember now the convo about this in the ClojureScript-dev channel.

didibus04:05:16

So would this work in NodeJS though?

didibus04:05:54

Like is this a valid NodeJS require? Or would a NodeJS package needing to require something like that need to use the ESM module and use ES6 import on it?

thheller07:05:51

shadow-cljs has different rules for classpath-js. meaning that all the files you require from the classpath will be processed by it and will eventually even go through :advanced

thheller07:05:56

node will never see that file, it will already be written and be like the CLJS output as far as node is concerned

thheller07:05:01

but there are some issues with node so it might not always work

thheller07:05:24

all fixable but not much time to work on it

rgm05:05:59

nope, failure to compile with [Figwheel:WARNING] Could not Analyze: /_SLASH_example_SLASH_jsm_SLASH_loaders_SLASH_ColladaLoader.cljs is not a relative path src/frontend/rgm/browser/three.cljs … looks like it heads through clojure.core/munge someplace

rgm05:05:55

hm, weird. There’s a more recent third-party packaging of that loader that takes the form var collada = require('three-loaders-collada')(THREE);. Pretty sure I’d need to use a :foreign_libs and that JS stub re-publishing trick to disentangle that.

thheller10:05:18

this translates to

(ns 
  (:require
    ["three" :as THREE]
    ["three-loaders-collada" :as collada-init]))

(def collada (collada-init THREE))
no need for special compiler hacks, custom packages or anything of that kind

rgm14:05:59

Thanks Thomas! Seems to work. I had no idea I could just call the kinda-sorta-namespace node-provided ns as a function. It confuses clj-kondo, but I can live with that.

clojure
(ns rgm.browser.three
  (:require
   [reagent.core :as r]
   [three]
   [three-loaders-collada :as loader-init]))

(loader-init three)

(def *loaded-scene (atom nil))
(def scene (three/Scene.))
(def loading-manager (three/LoadingManager. #(.add scene @*loaded-scene)))
(def collada-loader (three/ColladaLoader. loading-manager))

(defn load-model
  []
  (.load collada-loader
         "/path/to/model.dae"
         (fn [model]
           (reset! *loaded-scene (.scene model)))))

rgm15:05:56

I still have a broader (though now academic) question: this loader does sit in the main three.js npm module. Is it strictly necessary to re-package it to its own manual, or is there a way to require/refer to it in the main npm module? (Though I guess this was enough of a problem outside of CLJS that there are 4 (!) separate third-party re-packagings on npm).

thheller17:05:08

I don't know the three package. if the file is part of the actual npm package then you might be able to directly require it via (:require ["three/wherever/the/file-is.js" :as x])

❤️ 4
rgm18:05:02

holy cow, that works!

rgm18:05:48

clojurescript this:

clojurescript
(ns rgm.browser.three
  (:require
   [three]
   ["three/examples/jsm/loaders/ColladaLoader.js" :as loader]))
turns into :target :bundle js that (via target/…/npm_deps.js)
js
module.exports = {
  npmDeps: {
    "three": require('three'),
    "three/examples/jsm/loaders/ColladaLoader.js": require('three/examples/jsm/loaders/ColladaLoader.js')  }
};

rgm18:05:02

and since ColladaLoader.js ends with export { ColladaLoader };, the loader becomes available to cljs as loader/ColladaLoader.

rgm18:05:12

oh, this is great to know.

rgm05:05:45

or rather, do the injection of the base THREE lib so that it can futz with enhancing its prototype. Ugh. Whyyy.

Franklin07:05:32

Hey 👋 , does anyone know where I can find an example of an app that uses reitit frontend and code splitting at the same time? one that I can look at on github just to see how it should/can be done. Thanks

danielstockton09:05:41

Is there a way to set goog.DEBUG to false when using optimizations none (nodejs build)?

danielstockton09:05:17

Can't get it working with optimizations simple, so staying with none is my best option at the moment.

thheller10:05:30

@danielstockton whats the issue? :simple should really just work as it doesn't do any of the problematic optimizations.

danielstockton10:05:38

Tried installing react/react-dom the same version as reagent with npm, clearing compiled files etc.. but couldn't get around it

thheller10:05:26

uhm you said nodejs? why is that including react-dom?

danielstockton11:05:01

It includes reagent.dom.server to render-to-string for server side rendering

danielstockton11:05:12

And i think reagent.dom.server requires react-dom

thheller11:05:23

do you use :npm-deps? ie. let the CLJS build process bundle the npm deps?

danielstockton11:05:57

No, just using lein cljsbuild to compile the node build and lein dependencies

thheller11:05:58

it doesn't. there is an extra react-dom/server.js

borkdude12:05:27

If you are using cljs devtools in chrome, please it let it be known here: https://twitter.com/ChromeDevTools/status/1263421789671239681

✔️ 36
borkdude12:05:14

They are planning to remove it.

rgm15:05:56

I still have a broader (though now academic) question: this loader does sit in the main three.js npm module. Is it strictly necessary to re-package it to its own manual, or is there a way to require/refer to it in the main npm module? (Though I guess this was enough of a problem outside of CLJS that there are 4 (!) separate third-party re-packagings on npm).

tekacs23:05:25

I did try poking at this a little, but I'm curious if anyone else has experienced this issue at all? I'm using fipp's pretty printer in CLJS and in Cursive's REPL I see the below -- in the browser, I get one js/console.log line per entry. It looks like fipp is running a single println per token...

bbloom23:05:24

@tekacs what version of fipp are you using? do you have this problem with a repl outside of Cursive?

tekacs23:05:16

@bbloom 0.6.23 (the latest, I believe) and fipp.edn/pprint does the same thing in the browser REPL, without Cursive connected

tekacs23:05:13

where this is the line where the js/console.log is coming from... I guess print may have different (one line per call) behaviour when enable-console-print! has been run (presumably by something in my environment)?

tekacs23:05:57

So I'm able to work around this, given fipp's writer behaviour, by going with: (println (with-out-str (fipp.edn/pprint object-to-print))) for the time being

tekacs23:05:18

which isn't ideal (not sure how it handles large objects, etc.), but certainly can work

tekacs23:05:27

thanks so much for your work on fipp, whilst I'm here :)

bbloom23:05:02

i haven’t been a clojurescript user in quite a while, so i’m not sure what the expected behavior is these days, but iirc, i always used to enable-console-print!

bbloom23:05:11

if you can’t for some reason, feel free to file a ticket against fipp w/ details

👍 4