This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-07-20
Channels
- # aleph (3)
- # beginners (14)
- # cider (70)
- # cljdoc (30)
- # cljs-dev (1)
- # cljsjs (6)
- # clojars (7)
- # clojure (88)
- # clojure-greece (1)
- # clojure-italy (3)
- # clojure-nl (17)
- # clojure-spec (1)
- # clojure-uk (54)
- # clojurescript (48)
- # code-reviews (2)
- # cursive (28)
- # datascript (3)
- # datomic (20)
- # docs (1)
- # emacs (16)
- # figwheel-main (17)
- # fulcro (13)
- # graphql (2)
- # hyperfiddle (2)
- # jobs (2)
- # nyc (1)
- # off-topic (39)
- # parinfer (1)
- # re-frame (37)
- # reagent (225)
- # remote-jobs (3)
- # ring (3)
- # ring-swagger (1)
- # shadow-cljs (110)
- # spacemacs (10)
- # spirituality-ethics (1)
- # test-check (3)
- # tools-deps (36)
- # uncomplicate (2)
- # vim (7)
@richiardiandrea I've had to inject an env param on clj side, but haven't had to work on that on cljs side. Have you checked what is inside the environ? If nothing, perhaps there's a param to put something in there depending on which profile you are running
@richiardiandrea no there is no built-in closure define for that. why do you want a :node-script
without a :main
though? wouldn't the generic node-repl
work then?
Does shadow do something different with macros? I'm getting "undeclared Var" for using JS module from inside a macro, though the actual use is in #?(:cljs)
26 | #?(:cljs (deficon postilaatikko "0 0 46 54"))
----------------^---------------------------------------------------------------
Use of undeclared Var reititin.icons/SvgIcon
to answer your question though: no, shadow-cljs does not do something different with macros
Though then I did use mui/SvgIcon instead, since cljsjs used a big bundle anyway :thinking_face:
if a symbol is with a namespace the macroexpand
will leave it alone. if its without symbol the unquote will try to qualify it
@thheller What would be the recommended way to load css files in npm modules, what in webpack world would be handled by the file loaders?
currently thats not supported. I have a few plans for that but didn't have time to work on it
ie. codemirror or react-table. they just contain css files in the npm module but don't refer to them from the JS
its a webpack-only thing to refer to css files from JS files and I hope it doesn't become more widespread
I suppose so that if anything requires the module, then the style is injected into head first
In any case, that was the last missing piece. I just downloaded the css as a static file into the project, which is a bit ugly. Have to remember to update it, if I ever update leaflet. But... things work now!
extracting the require("./thing.css")
is easy enough as they are already filtered out
just copying some css is super easy. the problem comes when you need to process scss
or @import "./another-file.scss"
not hard at all. you can do it all via build hooks. https://shadow-cljs.github.io/docs/UsersGuide.html#build-hooks
Hm, so this wouldn't even require modifying shadow-cljs, and could be done via pure config?
doing it performant without repeating all the work constantly in watch
is a bit more complicated though
no modifications to shadow-cljs are required. all the build data is available in the build hooks. you just extract what you need.
granted that basically nothing of the build data is documented and finding the right thing to extract might be difficult
Somehow I have the habit of always ending up on the rocky paths, so to speak, when it comes to Clojure
A coworker keeps getting amazed at it, always talking how his experiences have been so smooth
well its rocky if you expect things to work like webpack. Clojure isn't like webpack or npm
and my past experiences with either npm
or webpack
have been far from smooth. quite the opposite actually.
This is a rather more common than just working node modules, or even clojurescript in general.
It took me less than a month to end up looking at clojure source itself to figure out what's happening in a rare case
Do you think documenting an example build-hook would be a good solution, or would it be better still to do some changes into shadow-cljs that would handle it automatically, when it sees a package.json with "style"?
as I said: I do have plans for a built-in solution but that will take some time. currently too busy with other stuff.
I think that a build-hook would be useful too though and it will be impossible to cover every single scenario
Sorry, didn't mean that you should reprioritize, but I was wondering if this is something I might be able to do
what exactly do you want to do? build-hooks may be one solution but you might not even need those
If you think it makes sense for shadow-cljs to automatically inject the css files for modules it sees having that in package.json, without any extra config, I could try to implement that
You said you had plans or ideas already, so if with those I wouldn't even need the build-hooks, maybe I could just as well help solve this for everyone
plans for extracting the data and making it available to other tools (such as build hooks)
(ns demo.hooks
(:require [shadow.build.data :as data]
[shadow.build.npm :as npm]))
(defn dummy
{:shadow.build/stage :flush}
[{:keys [npm] :as state} & args]
(let [used-npm-modules
(->> (data/get-build-sources state)
(map :package-name)
(remove nil?)
(into #{}))
styles
(->> used-npm-modules
(map #(npm/find-package npm %))
(map :package-json)
(filter #(get % "style"))
(into []))]
(prn [:styles styles])
(prn [::flush args used-npm-modules]))
state)
this will find all the npm
packages that were used in the build and give you the package.json
data to work with
Certainly will. Can build-hooks work on closure defines, or have some other way to communicate to CLJS/JS code that "here's the list of CSS files you should inject before doing anything else"?
Inject into <head>, either the links to the static CSS files copied to the output dir, or as <style> tags inlining the CSS
you could copy the css files to the output dir yes. how that ends up in the HTML is up to you
Of course the best (perhaps the "right") way to do it would only trigger when any code actually requiring the given npm lib is loaded, so that big CSS files are not downloaded without actual need
Yes, I'm trying to figure out if the build-hooks have a way to set some environment where the other part could pick it up, for example some code in the main cljs code
if you write the CLJS code to inject something I can tell you how to get the data there
Mm, I'll try to rephrase that... if using code splitting, only at the point the relevant parts are loaded
just have to work through :build-modules
instead of :build-sources
. :build-modules
is a vector of maps. each will have a :sources
key which lists all the sources included in that module
but right now I don't understand how you are planning to inject the CSS files via CLJS
I was thinking that the CSS files are static, but the tag to load them would be loaded just in time for the code that needs it. Or alternatively I was really thinking about inlining the whole thing, as I think JSS does it.
So when the cljs requiring leaflet is loaded, <link href="vendor/leaflet/leaflet.css" rel="stylesheet" type="text/css"> is added to head just before
yeah but you first have to load the JS, parse it, execute it, then that adds the css which the browser then downloads etc
thats a gazillion times slower than having the browser download it in parallel with your JS
I still wouldn't want to add it manually, even if it's in the static index.html. So, you'd say that serving the html via template, or building it via template into a static file would make more sense?
what I would do it extract all the referenced styles and then per module create a corresponding .css
file. so for :modules {:main {:entries ...}}
which creates a main.js
I would create a main.css
and include that statically via the HTML when including the main.js
but it all completely depends on what you are building. your requirements might be different.
Caching isn't that important at this point for the CSS files, so bundling into a single main.css could work. @imports in the main.css would add roundtrips as well, so I don't think I'd go that route. But might as well build the html file when building the js bundle, so that it would include all the separate css files too.
I would try to resolve the imports and so that you only have one css file per module
in my work projects I use a very simple node-sass
setup which has been good enough for me for years
Thanks for your input and help. I'll save these snippets and the discussion, and I'll get back to you after I've worked on a good enough start for the tutorial to get some feedback on, and include the build-hook there too.
Hello all again - I have another question (I don’t know if there is a short answer or not): I came to shadow-cljs because of the need to convert an older Vaadin based application part of which I would like to reimplement in ClojureScript, but still using at least one Vaadin grid component from their JS/React based framework which because of that would theoretically be usable from ClojureScript. The part which I don’t know is (by lack of enough experience in later years around all facets of JS and its build processes/frameworks) if it is possible to use it through shadow-cljs (or vanila cljs) while it is delivered under a NPM (as a wrapper) and (the actual build recipe) Bower build. I understand that the problem has several steps in the doability (can Closure process it, if not, how does it present its namespaces to Closure/cljs/shadow-cljs, is that understood from the build chain, the Bower config is not a single module description, but a bunch of dozens smaller components from the framework and related js libraries, is there a single js file produced at the end of Bower which can be accessed from cljs/Closure etc etc.) If anyone can shed some light into it I would be thankful.
Well it probably doesn't make any sense to somehow try to build the library component with shadow. But there's no need, also. As it works as npm module, it should work just fine.
Unless there are some "interesting" output formats where a npm lib is supposed to only work with other bower projects, and not offering a built ES, commonjs, AMD, or UMD module. Or just a var in global scope
@plamen I'm gonna need more details about the build setup otherwise I can't make any suggestions. I don't know Vaadin or how bower is involved. If everything is normal JS it should be easy to consume but looking at the demo application it seems to construct everything together from HTML files, eg. https://github.com/vaadin/expense-manager-demo/blob/master/src/content-panel.html
closure has some built-in support for polymer but I never used that so it might not work properly
hi, I’ve seen some notes around pulling in aws-sdk. Not sure if there’s a new issue or i’m doing something wrong ["aws-sdk" :refer [AWS]]
or ["aws-sdk" :default AWS]
are resulting in a null AWS
Hi @plamen I’ve actualy done quite a bit of Vaadin development, but need a little more info. How old is the app? Prior to v10 they had both the legacy java/gwt stuff and then introduced the Polymer (not React) based ‘elements’ in the v8 timeframe as a separate sort of parallel option. That was a stepping stone to the new Flow architecture in v10 that basically unified all of that. The Polymer based stuff is ultimately just javascript so you could potentially use it from clojurescript, but I’ve not tried it myself. There was a clojure wrapper for the v7/8 java stuff, i’m not aware of anything for the client stuff. But it’s again, just javascript. One word of caution though. While clojure/script tends to make everything more wonderful, Vaadin’s (and Polymer’s) programming models are not functional/reactive, but object based, and even in Clojure(script) don’t feel nearly as nice as the react-based stuff in the clojurescript ecosystem. That Clojure wrapper for the java stuff, did reduce some of the cruft and ceremony, but you were still very much ‘programming objects’. There have been a couple libs, like RxVaadin, that tried to make it more FRP’ish, but those were also pretty clunky to implement.