Fork me on GitHub
#cljs-dev
<
2023-02-28
>
djblue22:02:38

If I'm implementing a https://cljs.github.io/api/cljs.js/#STARload-fnSTAR for bootstrap cljs and trying to implement npm integration, where should the value of an npm module be written? For example, how is the following resolved / linked?

(ns  (:require ["react" :as react]))

(react/createElement ...)
I can fetch the code for react, evaluate it in a closure, but where should it be assigned to make it available to the cljs code?
window.react = <value of npm module>
Is this something I need to do via the goog.provide?

djblue22:02:33

I hope this is the right place to ask this question as it's a pretty low level question, but sorry if it isn't.

thheller23:02:55

in shadow-cljs I do this by creating a fake namespace which I then assign later, so (:require ["react" :as react]) essentially becomes (:require [that.fake.ns :as react]). any access to react/createElement is just turned into that.fake.ns/createElement by the analyzer. The fake ns is then just goog.provide("that.fake.ns"); that.fake.ns = require("react"); basically

👍 1
djblue00:03:42

Do you have an handy link to this code?

thheller06:03:30

yeah, note that in shadow-cljs the ns is parsed twice. once for resolve once for analysis. so the first pass gathers all the requires and builds the depedency graph. the second does the replacement and compilation.

thheller06:03:31

so we already know what we need to replace. not sure it works this way with bootstrap, but probably does?

thheller06:03:40

note that shadow-cljs also replaces this part of the analyzer completely. the original parse-ns was full of side effects and other mysteries. I just wanted something that parsed the ns form to be processed elsewhere. not mixing the processing and parsing. so, you are probably better off looking at cljs.analyzer/parse-ns directly

djblue06:03:19

I'll probably switch to something like that after I get everything working, for now (set! ana/node-module-dep? string?) seems to do the trick, although now I'm running into issues with clojure -> cljs aliasing

thheller06:03:57

hmm should be. this is done in cljs.analyzer/resolve-var usually

djblue06:03:04

Thanks for the pointer, I'll take a look 🙏

thheller23:02:40

not sure if you can do this alias replacement in bootstrap though. I believe it creates a var in the ns that did this. so my.app.module$react = require("react"); and react/createElement resolves to my.app.module$react.createElement.

thheller23:02:19

I mostly avoided this to only have the react reference once, and not once per ns using it.

thheller23:02:38

I might be wrong on the CLJS part though, haven't looked at the impl in a long time and never in a bootstrap context.