This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-06-21
Channels
- # announcements (9)
- # beginners (222)
- # boot (11)
- # calva (40)
- # cider (1)
- # clj-kondo (10)
- # cljs-dev (1)
- # cljsrn (8)
- # clojars (4)
- # clojure (50)
- # clojure-dev (4)
- # clojure-ecuador (1)
- # clojure-europe (4)
- # clojure-italy (3)
- # clojure-madison (2)
- # clojure-nl (26)
- # clojure-spec (86)
- # clojure-uk (34)
- # clojurescript (11)
- # clr (1)
- # cursive (46)
- # datomic (19)
- # emacs (4)
- # events (1)
- # fulcro (22)
- # graalvm (4)
- # graphql (2)
- # jobs-discuss (40)
- # leiningen (10)
- # luminus (6)
- # nrepl (7)
- # off-topic (18)
- # onyx (6)
- # overtone (1)
- # pedestal (2)
- # planck (1)
- # re-frame (5)
- # reagent (3)
- # reitit (8)
- # rewrite-clj (2)
- # shadow-cljs (139)
- # sql (4)
- # tools-deps (42)
Hi, Im running 2 react apps with shadow-cljs on 1 document which is causing react-errors. Im using output-wrapper configurations for both apps https://shadow-cljs.github.io/docs/UsersGuide.html#output-wrapper. The react error is telling me that there are probably multiple copies of React loaded
Both have an own version of React
which might be a problem
https://github.com/thheller/shadow-cljsjs/blob/master/src/main/cljsjs/react.cljs Could this be a problem? That each app exports react to the global variable “React”
yes that would be a problem. but having 2 versions of react on the page is the actual problem
you are duplicating everything. not just react but also react-dom and probably other dependencies
This is because we are creating a addon for JIRA, where everyone needs to package it's own version
Which absolutely sucks but that is we way Atlassian wants us to do this...
then you must avoid the cljsjs.*
packages. using (:require ["react" :as x])
will not expose the global
I was afraid of this, so we need to patch Fulcro 😞
but then you are relying on some foreign defined version of react which is kinda bad 😛
Yeah and fulcro contains code like this: js/React.createElement
I don't think we can patch that right?
Oh that would be fine 😛
I could probably just add a string/replace
then
so in theory if you get var React = the.actual.react;
into the output-wrapper that should be fine
that makes sense
so what I would probably try is creating a dummy ns that abuses js*
and is loaded first
(ns hack.react (:require ["react" :as react] ["react-dom" :as react-dom])) (js* "var React = {};" react) (js* "var ReactDOM = {};" react-dom)
That will be easy
Nice I will try this out, thank you so much
Yes makes sense
either by using :modules {... {:entries [hack.react
or by just requiring it first in whatever ns is loaded first
Awesome, will report back if it works
If you are interested in that 😛
Well this is annoying:
2019-06-21 15:57:52.567 - INFO] duplicate resource cljsjs/react/dom.cljs on classpath, using jar:file:/home/mitchel/.m2/repository/thheller/shadow-cljsjs/0.0.18/shadow-cljsjs-0.0.18.jar!/cljsjs/react/dom.cljs over file:/home/mitchel/Development/atlas-crm/atlas-crm-kit/src/cljsjs/react/dom.cljs
[2019-06-21 15:57:52.577 - INFO] duplicate resource cljsjs/react.cljs on classpath, using jar:file:/home/mitchel/.m2/repository/thheller/shadow-cljsjs/0.0.18/shadow-cljsjs-0.0.18.jar!/cljsjs/react.cljs over file:/home/mitchel/Development/atlas-crm/atlas-crm-kit/src/cljsjs/react.cljs
it keeps choosing the wrong one
Hmm wait I think order matters just as in maven
Stupid classpaths
I fixed it by forking shadow-cljsjs
Unfortunately it does not work:
Oh and for extra fun we use modules, so it generates this:
So if you have any other hacks I am all ears
Thnx will think about this some more
Damn it seems to work!
Nope false alarm 😞
It is weird this: (js* "var React = ~{};" react)
results in React=null;
(js* "var React = ~{};" r)
(js/console.log "react" r js/React (identical? r js/React))
So I have created this:
(ns atlas-crm.server.react-hack
(:require ["react" :as r]
["react-dom" :as rd]))
(js* "var React = ~{};" r)
(js/console.log r)
(js* "var ReactDOM = ~{};" rd)
(js/console.log rd)
And this results in:
React=null;console.log(nl_avisi_atlascrm.A0);ReactDOM=null;console.log(nl_avisi_atlascrm.L7a);
I also find this in resulting JS now: nl_avisi_atlascrm.A0.createElement,a,b,c
So that seems correct
I am trying it out now with the new name
omg the var definition fixes al of the renaming.. that is interesting
WTF=null;console.log(nl_avisi_atlascrm.A0);
And now the rest of the code is React.createElement,a,b,c
again
I guess its a problem in the closure compiler since React
is declared in the externs and you are not allowed to reassign it maybe?
Ah maybe that is problem, but it does rename all the references
which is good 😛
For our use case
So our code now contains instead of:
React.createElement,a,b,c
nl_avisi_atlascrm.A0.createElement,a,b,c
All of the cljsjs code get replaced by the correct var
After I added the
(js* "var React = ~{};" r)
(js* "var ReactDOM = ~{};" rd)
It changed all the code to:
nl_avisi_atlascrm.A0.createElement,a,b,c
Yeah that is awesome
but unexpected I guess?
it isn't unexpected. it is exactly how :modules
is supposed to work. I just don't get why it is assigning var React=null;
nl_avisi_atlascrm.A0=(6)
Awesome, yeah the only weird part is that it assignes React=null
Yeah but it does it in the global scope
Yeah that is the only problem
But I could even make regex after which removes that code 😛
but there should be no react in the global scope? isn't the goal to get rid of that?
So we are embedded in another application, So if that application decides to use React we don't want to set that to null
nl_avisi_atlascrm.$module$node_modules$react$index$$.createElement.apply(null, $arr$jscomp$166$$);
this seems correct :thumbsup:
Sorry I gotta go be back in a hour or so
Fighting with my terminal and escaping
if it works I'd just regex out the react=null
assignment for now. no idea where that is coming from or if that somehow can be removed otherwise
Yeah we will be doing that probably
I found this btw:
nl_avisi_atlascrm.$module$node_modules$react$index$$ = nl_avisi_atlascrm.$shadow$js$require$$(6);
That seems to be correct
I had to fork shadow-cljsjs btw to get this working
https://github.com/mitchelkuijpers/shadow-cljsjs So do you want me to try removing the externs to see if it assigns React?
I did that but shadow kept insisting that the shadow-cljsjs files win
No we have a shared modules
because we have about 6 projects who work like this
And we don't want to copy all of this stuff around
I’m having some trouble importing an npm package, specifically router5. When I require it via ns
(like: (:require ["router5" :as router5]))
) and try to use one of the exported functions (`createRouter`) I get TypeError: module$node_modules$router5$dist$index.createRouter is not a function
, and looking at the actual export it is in fact an empty object. But, if I’m in the browser repl and do (require '["router5" :as router5])
I can use the exported functions just fine.
Also, node_modules/router5/dist/index.js
is a commonjs file, with exports like:
exports.RouteNode = RouteNode;
exports.transitionPath = transitionPath__default;
exports.createRouter = createRouter;
exports.cloneRouter = cloneRouter;
exports.constants = constants;
exports.errorCodes = errorCodes;
exports.default = createRouter;
@colinkahn add a (js/console.dir router5)
to the file using it
@thheller not sure what’s different now, but yeah, console.dir worked, and then console.log worked, and now everything works. Is there some cache besides the output dir that could be holding onto some local change? I’m not eager to get it to break again but it is a bit worrisome that it didn’t work one minute and now it does
How we can build a library to be used by ClojureScript projects with Shadow-cljs?
One option is node-library
which I think is npm deployable. But how can a .jar
file be made which can be deployed on Clojars?
@ahmed1hsn shadow-cljs doesn’t provide a way of bundling CLJS for publishing as a library. I typically use leiningen and lein deploy
to publish to e.g. clojars or other maven repo
the important thing is, you don’t need to compile your clojurescript code at all
Thanks @lilactown. What about npm dependencies I required in the deployed library? Will users of library have to include npm modules in package.json
and just start using it?
And if there are other CLJS dependencies with .jar
format, they can be included in :dependencies
in project.clj
. Right?
CLJS dependencies can be included in project.clj and will be automatically installed yeah.
There's not a dependable way to install npm dependencies automatically, so I usually include it as part of the installation instructions to manually install them via npm when adding it to their project
@ahmed1hsn for JS dependencies you can add a deps.cljs
to your .jar
with {:npm-deps {"foo-bar" "1.2.3"}}