This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-02-03
Channels
- # announcements (8)
- # aws (2)
- # babashka (16)
- # beginners (173)
- # calva (13)
- # cider (4)
- # cljfx (6)
- # cljs-dev (108)
- # clojure (63)
- # clojure-australia (2)
- # clojure-dev (10)
- # clojure-europe (73)
- # clojure-italy (8)
- # clojure-nl (4)
- # clojure-norway (5)
- # clojure-uk (4)
- # clojurescript (49)
- # clojureverse-ops (4)
- # community-development (3)
- # core-async (23)
- # cursive (3)
- # data-science (5)
- # datomic (25)
- # emacs (3)
- # events (1)
- # fulcro (13)
- # helix (5)
- # introduce-yourself (1)
- # lein-figwheel (1)
- # lsp (36)
- # malli (1)
- # meander (2)
- # membrane (4)
- # music (8)
- # nextjournal (51)
- # off-topic (47)
- # other-languages (5)
- # pathom (31)
- # pedestal (5)
- # planck (14)
- # polylith (5)
- # portal (1)
- # re-frame (30)
- # react (2)
- # reagent (24)
- # releases (1)
- # rewrite-clj (18)
- # ring (9)
- # sci (33)
- # shadow-cljs (49)
- # testing (3)
- # tools-build (21)
- # tools-deps (29)
- # vim (19)
- # web-security (1)
- # xtdb (12)
You write your own thing that requires the generated CLJS entry point and you feed the bundler your entry point
Does anyone use material-ui in the clojurescript. I am trying to use https://github.com/arttuka/reagent-material-ui in my codebase but unable to use make-styles and styled-component type of thing. I try to replicate this simple code in cljs but it is not working REACT CODE
import * as React from 'react';
import { makeStyles } from '@mui/styles';
import Button from '@mui/material/Button';
const useStyles = makeStyles({
root: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
});
export default function Hook() {
const classes = useStyles();
return <Button className={classes.root}>Hook</Button>;
}
CLJS CODE
(ns
(:require [reagent.core :as r]
[reagent.dom :as dom]
[reagent-mui.material.button :refer [button]]
[reagent-mui.jss-styles :refer [make-styles with-styles styled with-theme]]
))
(defn usestyles [] (make-styles {
:root {:background "linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)"
:border 0
:borderRadius 3
:boxShadow "'0 3px 5px 2px rgba(255, 105, 135, .3)'"
:color "white"
:height 48
:padding "0 30px"
}
}))
(def classes (usestyles))
[button {:class-name (:root classes)}
"Hamza"]
yes yes I have extensively use make-styles in the react codebase but somehow it is not working in cljs codebase
it will be a great favor if you share the link ?
No, not in the React codebase. Read the documentation specifically of the reagent-mui.jss-styles/make-styles
.
For some reason cljsbuild
is adding the following errors to my compiled JS. Any hints as to why this might be happening?
// Compiled by ClojureScript 1.10.764 {:language-out :ecmascript-next}
Warning: environ value 8u312 for key :java-version has been overwritten with 1.8.0_312
Warning: environ value /usr/local/openjdk-8 for key :java-home has been overwritten with /usr/local/openjdk-8/jre
seems I needed to set JAVA_HOME
and JAVA_VERSIONS
for the compile command: something like this;
root@cf144c04da13:/tmp# JAVA_HOME=/usr/local/openjdk-8/jre JAVA_VERSION=1.8.0_312 lein doo chrome-headless-no-sandbox test once
@mikerod fwiw, :bundle :target
is intentionally simplistic because it was clear that there's a lot of patterns that need to be supported that we don't necessarily want to write into the compiler
@dnolen Yeah, I can certainly understand that & I figured that was the case. I want to try this extra level of indirection idea today & see how it goes. I’m also looking to see how it works if I’m using the :bundle :target
as a cljs-library too. I’m curious how much work/redundancy it will be on my other app’s config that use this lib. They’ll have to also pull the CSS, which is somewhat of a “transitive dependency” to them at that point - if that makes sense.
the idea being that, :bundle :target
leaves the door wide open for anyone to produce affordances and reduce boilerplate
That’s quite interesting. I wish there were more publicly shared examples of doing things a bit more sophisticated like this. Just to get a look at how people have addressed some of these fairly common concerns. Your work sounds certainly relevant.
I’m trying to migrate over to :bundle :target
. I was doing it all manually before. The way it was described prior to :bundle
helping out. I think it is looking promising though at some good boilerplate reduction. This could definitely be a good thing for my org where the old way has quite a bit of steps to enumerate in each project we do (which is a growing number).
Yeah. My situation is basically we have a common UI “components” library that we use by a bunch of our actual top-level applications.
Prior to :bundle :target
, there was basically this boilerplate, webpack config + webpack entry point + npm package.json + CLJS :foreign-libs
declaration that the library project used itself for testing, but also all my top-level applications also had to replicate basically the same way so the “transitive npm deps” were brought in as needed by the library.
So my hope with :bundle :target
was that the “downstream” top-level applications will no longer have to repeat so much of this boilerplate. I haven’t gotten that far yet though.
The CSS was one thing I immediately noticed I’ll have to still have a pattern for.
Some of the npm dependencies my UI “components” lib has have css that you’d typically bring in via, eg.:
import "react-resizable/css/styles.css";
I cannot just use a CDN or some external reference to it in my particular case since my top-level applications need to be basically “self contained” because the env they are deployed in cannot call out to arbitrary public IPs (an on-premise/firewalled sort of usage).A separate question from me. I have tried to post it on http://clojureverse.org, but I’m having difficulty with it allowing me to post topics for some reason (WIP). Using this setup: deps.edn
{:deps {org.clojure/clojurescript {:mvn/version "1.11.4"}}}
src/example/macrotrouble/core.cljs
(ns example.macrotrouble.core
(:require [example.macrotrouble.util :as u]))
(def o (js-obj "x" 10))
(u/defprop my-x o "x")
src/example/macrotrouble/util.cljc
(ns example.macrotrouble.util
#?(:cljs (:require [goog.object]))
#?(:cljs (:require-macros [example.macrotrouble.util])))
(defmacro defprop [n o prop-name]
`(def ~n (goog.object/get ~o ~prop-name)))
Then running:
clj -M --main cljs.main --compile example.macrotrouble.core --repl
The browser JS console immediately shows:
Uncaught TypeError: Cannot read properties of undefined (reading 'get')
at core.js:8:84
The same can be recreated at the repl, via require
+ :reload
of the ns in question.
The fix is to also require
the “invisible” goog.object
usage of the core ns coming from the macro expansion:
(ns example.macrotrouble.core
(:require [goog.object]
[example.macrotrouble.util :as u]))
This surprised me due to the fact that it is leaking out that the macroexpansion is requiring other ns’s. Is this some special issue only occurring due to it being a goog.*
ns?This is not specific to goog
stuff - it's a proper fix and you have to use it for all such namespaces.
macros cannot emit a direct use of goog.object
anymore since https://clojurescript.org/news/2021-11-04-release
Yeah, I am fine with just wrapping the calls in a wrapper “normal fn”, if that means the callers do not have to care about it
its a bit annoying but goog.module namespaces are now basically a local reference. so it ends up missing when the ns that the code ends up in doesn't have it.
I did read that blog post before originally and just assumed it meant if I actually left off the :require
in the macro definition ns.
you can safely assume this for ClojureScript namespaces as that aligns w/ Clojure expectation, but not GCL