This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-07-26
Channels
- # aleph (1)
- # beginners (96)
- # boot (5)
- # cider (44)
- # cljdoc (11)
- # clojure (73)
- # clojure-conj (4)
- # clojure-dev (1)
- # clojure-finland (2)
- # clojure-italy (7)
- # clojure-new-zealand (1)
- # clojure-nl (3)
- # clojure-spec (4)
- # clojure-uk (66)
- # clojurescript (114)
- # code-reviews (16)
- # cursive (15)
- # datomic (37)
- # emacs (6)
- # events (2)
- # figwheel-main (12)
- # fulcro (36)
- # graphql (19)
- # hoplon (2)
- # hyperfiddle (3)
- # jobs (2)
- # leiningen (4)
- # off-topic (36)
- # om (1)
- # om-next (2)
- # other-languages (1)
- # re-frame (12)
- # reagent (12)
- # reitit (5)
- # remote-jobs (4)
- # ring (2)
- # shadow-cljs (218)
- # spacemacs (8)
- # specter (7)
- # sql (34)
- # tools-deps (9)
- # uncomplicate (6)
shadow-cljs watch app
(shadow/watch :app)
=> :already-watching
(shadow/nrepl-select :app)
To quit, type: :cljs/quit
=> [:selected :app]
(js/alert "foo")
No application has connected to the REPL server. Make sure your JS environment has loaded your compiled ClojureScript code.
I have opened website in Chrome. What I miss?if you want something easier to just test nrepl and stuff you can run shadow-cljs browser-repl
and then (shadow/repl :browser-repl)
in the REPL to select it
is it possible to merge certain keys from a build config? for instance, i want to create a dev build that uses all of the “release” entries, plus 1 more?
@thheller Have you thought about using rebel-readline
in the various REPLs that shadow-cljs provides?
@biscuitpants see https://shadow-cljs.github.io/docs/UsersGuide.html#_release_specific_vs_development_configuration
sweet thank you @thheller
loader-mode eval is amazing!
@samuel.wagen I have not. I only use the REPL from my editor so readline
support doesn't do anything for me and thats why I haven't worked on anything related yet.
@thheller fair enough. do you have any pointers where to start, if I want to try adding it myself?
no concrete metrics, but i can feel the difference in the browser. before, without eval loader mode, the browser would have at least 2 seconds of lag, appending all the goog scripts. now, nothing. our “loading” symbol doesn’t even show anymore! 😄
@samuel.wagen no idea. you can probably use it out of the box for the CLJ REPL
I'm guessing that is pretty tightly integrated with the cljs.repl
APIs which wouldn't work with shadow-cljs
oh well 🙂 I'm using vim-fireplace, and I find myself not liking it much and preferring to use the cljs-repl instead.
I'll probably work on adding history support, completion and all that stuff at some point
I know of it, but I prefer a terminal split instead of yet another browser window/tab - it's less context switching for me.
thats why I do have plans for a chrome extension which would put the REPL into your browser devtools 😉
that would be cool to have, for sure. for my use case though, I love the cljs-repl feature of showing the println
output in the repl in addition to having it in the devtools console - helps me use devtools less and stay nearer my editor
I have tried several times to switch to Emacs for the better integrated REPL, but it's just not for me, even with evil-mode. Anyway, that's irrelevant. Maybe I'll be able to add some more creature comforts to cljs-repl even without directly using readline-rebel
well I do have plenty of plans for all of this but just not enough time to actually do it
ain't that the case with all of us 🙂 in any case, your efforts are greatly appreciated, shadow-cljs has been much more pleasant experience than the alternatives, at least for me
https://github.com/ethereum/web3.js
(ns boilerplate.example-test
(:require [cljs.test :refer [deftest is testing use-fixtures]]
["web3"]))
(println (pr-str (js/Web3.)))
How to do:
var Web3 = require('web3');
var web3 = new Web3();
I was trying a few ways, but always ReferenceError: Web3 is not defined
Well, in 0.14.0 you should be able to use (:require ["web3" :as web3])
in your ns
definition.
For future reference: https://shadow-cljs.github.io/docs/UsersGuide.html#npm
(ns boilerplate.example-test
(:require [cljs.test :refer [deftest is testing use-fixtures]]
["web3" :as web3]))
(println (pr-str (js/web3.)))
console.log(web3); // {eth: .., shh: ...} // it's here!
Can I print it without webrowser?
Not sure I understand. You mean you want the contents, not the [object Object]
, and you're using CLI, not a browser console?
shadow-cljs watch node-test
<- at that moment i am running tests, so it is not in web browser
You can try (js/console.log web3)
. If that doesn't change anything, there should be other members of js/console
, like dir
. But I have no idea whether they're supported during the test run.
@thheller How bad is it to override functions defined in some other ns? Will it work? Will it be predictable? I have some issues with Reagent, and I really don't want to include the whole library just to change a couple of functions.
I've found cljs.core/find-ns-obj
, but it's in the section titled "Bootstrap helpers - incompatible with advanced compilation". I have no idea how exactly they're incompatible though - they appear to use munge
, so at least symbol names should be correct.
@kwladyka If you're interested, you can take a look at https://github.com/reagent-project/reagent/issues/389 for more details. In essence, these functions that I'd like to change are used deep inside Reagent, so I can't just add my own implementation and tell Reagent to use it. I don't plan overriding to be a long-term solution. More like a piece of plumbing until the issue is fixed.
hmm Do js class need #js format instead of clsj? That is why it is converted. No idea, but it sounds reasonable.
The problem there is that all CLJS data passed to a wrapped React component is being converted into JS data structures. The issue is that it's impossible in the general case to convert the data back because CLJS->JS conversion is lossy.
> CLJS data passed to a wrapped React component is being converted into JS data structures. No reason for that?
Well, there's definitely a reason - just as you wrote yourself. The issue is that it's a reason for most of the cases, but definitely not for all of them. E.g. my component is not a true React component, but rather a wrapped Reagent component, so not only do I not need the conversion, but it straight spoils everything.
hmm not sure what you want achieve in practice, but are you sure adapt-react-class
is right function then? It sounds like you want use it with other purpose, than it was created.
What do you mean? The pure React wrapper that I want to use returns a React class, so I have to use adapt-react-class
. And it also accepts only a pure React class, so I have to use reactify-component
.
you can instead just take the original source file and put it in your source path with the changes you want
@thheller Yeah, I was thinking about that. But how do I make sure that my file has priority?
But hypothetically - would something like (set! reagent.core/adapt-react-class (fn [c] ...))
work?
Wait, what do you mean? Either I don't understand something, or your statement contradicts with what you already said.
it sort of works yes but you must ensure that the thing you are adding has the exact same signature as the original
yeah the set!
won't update the compiler/analyzer data so it may emit code that isn't compatible
back to the override issue: it works in your project since the project sources paths come first before the jars on the classpath
@kwladyka the code to match the JS example would be
(ns boilerplate.example-test
(:require [cljs.test :refer [deftest is testing use-fixtures]]
["web3" :as Web3]))
(def web3 (Web3.))
the more I use reagent, there are some things I love about it (the ability to represent my component tree as dumb vectors) and some things I hate (all of the magic)
if they had not included their own async rendering and special reagent classes then it would be so much more flexible. but perf would probably be terrible
to me (html/h1 "hello world")
looks just as nice as [:h1 "hello world]
but doesn't require vectors->reactelement translation
but then I started to wonder what the point was 😛 I'm starting to coming around to the parens (div "foo")
but we actually use the fact that the runtime representation of a reagent component is just a vector a lot at work
it turns out that it's much easier to traverse and transform than an actual React tree
we're doing server rendering of react components on Node.js, and are using the apollo library to do queries to a graphql endpoint.
on the server side we traverse the tree, fetch all of the data necessary to render it, and then call render-to-string.
using reagent + cljs it's a simple clojure.walk
algorithm with some clever binding
. with pure React it would involve calling the render
function or calling a special getData
method (which dan_abramov admonished the community for)
apollo is basically relay++ 😛 and tbh the reason I had to write my own SSR stuff is because we're using reagent and not apollo-react...
but om.next & fulcro didn't really fit our use case. we wanted to go all-in on React, and also we're not building an SPA
hmm… i know shadow can read json files, since it first goes to a lib’s package.json and traces from there. but what the heck might this be? The required JS dependency "node-releases/data/processed/envs.json" is not available, it was required by "node_modules/browserslist/index.js"
. my dependency postcss has a dep on browserslist, which has a dep on node-releases (which exposes the envs.json file). a double transient dependency resolution 😞
indeed, it was installed after i installed postcss (which lists the dep tree i mentioned)
[1:1]~cljs.user=> (require '["browserslist" :as x])
nil
[1:1]~cljs.user=> x
#object[browserslist]
yea i think that’s the same error i’m getting. the envs.json file is definitely there, and the require statement in browserslist is pointing to the right file
How does :npm-deps
compare to shadow-cljs
?
is possible export a js bundle that will be used in a template-like website (PHP/django that use many <script src=...>
), without risk to conflict with another bundle?
@souenzzo sure it should work by default. Its just not recommended to make multiple independent CLJS builds like that and loading them since each will contain their own cljs.core
version which would not be compatible with each other
if you only have one however CLJS build and the rest is non-CLJS that is not a problem
@dijonkitchen shadow-cljs
only compiles npm
dependencies with :simple
optimizations. :npm-deps
tries to do :advanced
. If that works its better but it rarely works so shadow-cljs
sacrifices that for more compatibility.
Yeah, I’ve had trouble with :npm-deps
but it should work, at least for simpler cases. Why does it rarely work?
:thinking_face: can I have two separate bundles (they're on separate pages) with the same module identifier?
@thheller I just need to delivery one script src='...'
with one function. But I dont know anything about the other scripts that this site will use.
@dijonkitchen it rarely works because the mess of JS that is on npm
. they don't follow the closure JS standards at all and sometimes to some dynamic stuff which the closure compiler doesn't understand. also the commonjs support is a bit lacking in places and some idioms the JS folks use are not supported at all.
shadow-cljs basically follows the model of webpack instead and matches that much more closely since most JS libs are sort of tuned for that
@lilactown what module identifier? if you mean :modules
no, that must be unique.
e.g.
:dashboard
{:target :browser
:modules {:main {...}
:onboarding {...}}}
:other-page
{:target :browser
:modules {:main {...}
:onboarding {...}}}
@thheller the main cljs compiler/the closure compiler itself has problems if there is 2 bundlers imported in the same browser #shadow-cljs solves that?
@lilactown thats two different builds, thats fine if you use different :output-dir
values
you should look into :app {:target :browser :modules {:common {...} :dashboard {:depends-on #{:common} ...} :other-page {....}}
instead
yeah getting :modules
just right is tough. always consider how the user moves though.
but the user would never access :admin
and some of the stuff in there made the base modules larger
so it was much better to have a separate :admin
build and keeping that out of normal user stuff
@souenzzo you can either do (defn ^:export your-fn [...])
to have your function accessible from HTML via <script>your.ns.your_fn();</script>
or you can use (defn your-fn [...]) (js/goog.exportSymbol "yourFn" your-fn)
to have it accessible as <script>yourFn();</script>
I'd suggest doing the second. otherwise you need to ensure that the NS you use doesn't clash with anything on the page, ie. ensure there is no your
variable in the example above
Hi, i’m trying to ‘transate’ some react jsx code over to cljs I read through the section on using babel to convert jsx’es to .js, got that working. but imports of other resources just work? Here’s a snippet
import "perfect-scrollbar/css/perfect-scrollbar.css";
import withStyles from "@material-ui/core/styles/withStyles";
import Header from "components/Header/Header.jsx";
import Footer from "components/Footer/Footer.jsx";
import Sidebar from "components/Sidebar/Sidebar.jsx";
import dashboardRoutes from "routes/dashboard.jsx";
import appStyle from "assets/jss/material-dashboard-pro-react/layouts/dashboardStyle.jsx";
import image from "assets/img/sidebar-2.jpg";
import logo from "assets/img/logo-white.svg";
So I get that after running babel I should be able to do something like
(require ["components/Header/Header" :default Header])
but does this also work for the css, images and what have you? like (require [ "perfect-scrollbar/css/perfect-scrollbar.css"])
@eoliphant importing non-js resources like that doesn’t work in shadow-cljs (it’s a webpack-specific extension)
webpack has a bunch of “loaders” that bundle up resources for you. people can get a bit obsessed with reducing the # of round trips a page load takes, but the reality is you can always bundle all your css into a single file using less or sass, so at most it is a single additional tag
in my index.html
, I just have a <link rel="stylesheet" href="/css/site.css">
in my <head>
tag
i’m sure there’s something more sophisticated, but that solution is simple and it works
god css is so terrible. I had been @import
ing library css into my main scss, but now it is deprecated. https://github.com/sass/libsass/issues/2611 The only clear solution is ‘use webpack’ (?) lol
import {
drawerWidth,
drawerMiniWidth,
transition,
containerFluid
} from "assets/jss/material-dashboard-pro-react.jsx";
const appStyle = theme => ({
wrapper: {
position: "relative",
top: "0",
height: "100vh",
"&:after": {
display: "table",
clear: "both",
content: '" "'
}
},
mainPanel: {
transitionProperty: "top, bottom, width",
transitionDuration: ".2s, .2s, .35s",
transitionTimingFunction: "linear, linear, ease",
[theme.breakpoints.up("md")]: {
width: `calc(100% - ${drawerWidth}px)`
},
overflow: "auto",
position: "relative",
float: "right",
...transition,
maxHeight: "100%",
width: "100%",
overflowScrolling: "touch"
},
content: {
marginTop: "70px",
padding: "30px 15px",
minHeight: "calc(100vh - 123px)"
},
container: { ...containerFluid },
map: {
marginTop: "70px"
},
mainPanelSidebarMini: {
[theme.breakpoints.up("md")]: {
width: `calc(100% - ${drawerMiniWidth}px)`
}
},
mainPanelWithPerfectScrollbar: {
overflow: "hidden !important"
}
});
libraries should haven’t jsx and inline css and crap like that. most library ship with compiled code
it’s just not going to be easy to make that stuff work with cljs without a build step. as i’ve said to thheller before: people don’t program in javascript anymore, they program in webpack. but most people are decent enough to build their code into something portable before shipping to npm
so many people use the webpack/babel stack that code is starting to assume that you are too. so you’ll need to set up a build step before using with cljs
presumably this node-sass-chokidar thing is tackling the css, also doesn’t look like it uses webpack (directly at least), it’s using react-scripts for the build
"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive",
"start-js": "react-scripts start",
"start": "npm-run-all -p watch-css start-js",
"build": "npm run build-css && react-scripts build",
that will build the css, but it won’t strip the webpack loader extensions out of the code. i.e., you’ll still have the import “blah.css” in the code, and that is going to make the js runtime choke