This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-06-14
Channels
- # announcements (2)
- # babashka (27)
- # beginners (20)
- # biff (1)
- # cljs-dev (2)
- # clojars (19)
- # clojure (50)
- # clojure-austin (10)
- # clojure-australia (8)
- # clojure-europe (23)
- # clojure-losangeles (1)
- # clojure-nl (1)
- # clojure-spec (7)
- # clojured (7)
- # clojurescript (19)
- # cursive (4)
- # datalevin (9)
- # datomic (15)
- # emacs (7)
- # fulcro (25)
- # gratitude (2)
- # helix (1)
- # holy-lambda (2)
- # hyperfiddle (14)
- # introduce-yourself (1)
- # jobs (5)
- # joyride (2)
- # juxt (3)
- # kaocha (9)
- # leiningen (14)
- # meander (9)
- # minecraft (34)
- # nbb (18)
- # off-topic (15)
- # polylith (12)
- # re-frame (4)
- # remote-jobs (1)
- # shadow-cljs (79)
- # vim (57)
I’m trying to set up a UI library using React+Typescript+Storybook+MaterialUI and consume it as a library in clojurescript. I’ve been able to export a commonjs file and require it from my reagent app, but the styles are not applied. Seems material ui uses css-in-js which I’m not familiar with. Grepping the dist file the styles seem to be present. Any idea how to debug this?
changing from commonjs output to esm seems to have worked. only snag is I have to edit the output file and replace
import * as React from "react";
with import React from "react";
the user guide says:
> Due to strict checking of the Closure Compiler it is not possible to use the import * as X from "npm";
syntax when requiring CLJS or npm code. It is fine to use when requiring other JS files.
I output an es module into a file foo.js
and require it like:
(ns my.ns (:require ["/foo" :as foo]))
. From the text quoted above shouldn’t this be fine?
and what do you mean by storybook? doesn't that have its own tooling and would require integrating the CLJS code in the JS code
yes, storybook is not relevant here.
i’m currently attempting to create a bundle using esbuild and including that. inspired by your usage of babel here: https://shadow-cljs.github.io/docs/UsersGuide.html#_javascript_dialects
not sure if this is fruitful or not, any suggestions would be greatly appreciated.
my goal is to have a setup inspired by nolan’s talk ClojureScript in the Age of TypeScript. I.e. frontend guys writes react components in typescript on storybook which they enjoy because of intelli-sense. and us few that swear to clojure can tie it all together in a small reagent app
ok then I suggest the following route. you build all your TS/JS whatever code into a folder
then in the shadow-cljs build config you set :js-options {:js-package-dirs ["packages" "node_modules"]}
basically you build the JS stuff as an npm package, without actually needing to publish it to npm
including it directly from the classpath I don't recommend since that gets different treatment and likely won't work without specific care
that sounds great, could you give me some pointers regarding build all your js code
? Could this be:
1. define an entrypoint
2. run it through esbuild?
I don't know if it needs any building. you mentioned esbuild so I thought you had the JS build part figured out
shadow-cljs will minify it anyways so you don't need to actually build anything as long as its JS code
far from it 🙂 learning though, but it’s a steep climb
ok, so a .jsx file would be fine?
:thumbsup: thanks, I’ll give it a stab
probably unsurprising to you, but this worked with a trivial react component. thanks a lot!
hello. an FYI for ppl using devcards. I found that upgrading shadow to 2.19.3 my previously working devcards setup had a couple of problems. I have some initial workarounds I wrote up here: https://github.com/jacekschae/shadow-cljs-devcards/issues/1
anyone using jspdf
with shadow-cljs?
I’m seeing this build failure after npm installing it. Seems that the closure compiler isn’t a fan of jsPDF’s minifier?
[:app] Build failure:
Closure compilation failed with 1 errors
--- node_modules/jsPDF/dist/jspdf.es.min.js:10686
Block-scoped variable Vt declared more than once. First occurrence: node_modules/jsPDF/dist/jspdf.es.min.js:9530:13
never can tell if they are actual legit errors or the closure compiler just parsing things wrong
you can try the non-minified version by requiring "jspdf/dist/jspdf.es.js"
instead of just jspdf
seems like the issue is with how jspdf packages itself and not just its minifier
[BABEL] Note: The code generator has deoptimised the styling of /Users/yedi/Documents/workspace/mobot/mobot-web/node_modules/jspdf/dist/jspdf.es.js as it exceeds the max of 500KB.
[:app] Build failure:
Closure compilation failed with 1 errors
--- node_modules/jspdf/dist/jspdf.es.js:3834
Block-scoped variable ga declared more than once. First occurrence: node_modules/jspdf/dist/jspdf.es.js:3834:4095
i wonder if it makes sense to use the cljsjs jspdf artifact if requiring it through npm doesn’t work… though i can’t imagine noone is using jspdf with shadow-cljs
hm new build failure with umd
[:app] Compiling ...
[2022-06-14 14:33:09.670 - INFO] :shadow.build.npm/js-invalid-requires - {:resource-name "node_modules/jspdf/dist/jspdf.umd.js", :requires [{:line 15743, :column 14} {:line 15777, :column 14} {:line 25168, :column 14}]}
[:app] Build failure:
The required JS dependency "worker_threads" is not available, it was required by "node_modules/jspdf/dist/jspdf.umd.js".
hmm yeah thats not any better. you can set :js-options {:resolve {"worker_threads" false}}
in your build config
no luck, we’re back to the ga
issue
[2022-06-14 15:36:04.439 - INFO] :shadow.build.npm/js-invalid-requires - {:resource-name "node_modules/jspdf/dist/jspdf.umd.js", :requires [{:line 15743, :column 14} {:line 15777, :column 14} {:line 25168, :column 14}]}
[:app] Build failure:
Closure compilation failed with 1 errors
--- node_modules/jspdf/dist/jspdf.umd.js:23062
Block-scoped variable ga declared more than once. First occurrence: node_modules/jspdf/dist/jspdf.umd.js:21353:15
not sure if this is relevant to shadow but I’m trying to require a module i’ve created:
// src/stack.jsx
import * as React from "react";
import Button from "@mui/material/Button";
function stack_default() {
return /* @__PURE__ */ React.createElement(Button, {
variant: "contained"
}, "Hello World");
}
export {
stack_default as stack
};
and render it using reagent:
(ns
(:require
[reagent.core :as r]
[reagent.dom :as rdom]
["components" :as c]))
(let [elem (.getElementById js/document "app")]
(rdom/render [:f> c/stack] elem))
it compiles fine but blows up with a lot of errors, notably:
• Warning: Invalid hook call. Hooks can only be called inside of the body of a function component.
• Uncaught TypeError: dispatcher is null
• The above error occurred in the <ForwardRef> component:
anybody seem something similar to this?this works though, which I don’t understand:
(ns
(:require
[reagent.core :as r]
[reagent.dom :as rdom]
["@mui/material" :as mui]))
(let [elem (.getElementById js/document "app")]
(rdom/render [:> mui/Button {:variant "contained"} "Hello World"] elem))
adding :entry-keys ["module" "browser" "main"]
seems to have fixed it :thumbsup:
no, still issues 😕 I have the following layout:
src/ <- on classpath
packages/foo <- a npm package
packages/foo/dist/index.js <- file I want
packages/foo/node_modules <- foo's dependencies
foo’s package.json has:
{
...
"module": "dist/index.js",
...
}
shadow-cljs.edn:
{:dependencies
[[reagent "1.1.1"]]
:source-paths
["src"]
:dev-http {8080 {:root "public"}},
:builds
{:app {:target :browser
:output-dir "public/js"
:asset-path "/js"
:js-options {:js-package-dirs ["packages" "node_modules"]
:entry-keys ["module" "browser" "main"]}
:modules {:main {:entries []}}}}}
seems shadow runs code from foo/node_modules
.
what i’m trying to say is:
1. look in packages before node_modules, and
2. try to import as es module first
anybody know how to achieve this?I think there’s an issue with js-package-dirs
being searched recursively, so my js module gets react from packages/foo/node_modules
while reagent gets it from node_modules
packages/foo
is a react components library written in typescript, developed with storybook.
it shouldn't have any node_modules
at all though. it should just be the output files of your JS build and a package.json
cause yes, otherwise it'll follow the node resolve rules and use nested packages if present
Understood. Was hoping to be able to develop in packages/foo
. What if the resolver excluded peer and dev dependencies found? Think that would work for this case.
😁 worth a shot. thanks for your input on this.
there is also :js-options {:allow-nested-packages false}
but I strongly recommend not setting it
in your main project you can also just npm install ./packages/foo
I believe. which would take care of copying stuff over to the local node_modules
. no need to :js-package-dirs
then
No. At least by default it symlinks, so same problem.
then in the package you can npm package
or whatever the command is and get a .tgz file which you can then install
But your former suggestion sounds good. Do i need to generate a package.json in out/foo
?
could just always have it there manually written and generate into a dist
folder like you had
Ok, why?
Asking because im sure ill get the question 😄
Include a package.json file in out/foo
. Seems it's not needed. Future proofing?
so without it resolve is missing an important piece and falling back to index.js
is just the last looked at option
Makes sense. Again, thank you for the guidance.