Hi everyone. Painfully noobish CLJS-er here. Just wondering why when I created a project folder with the npx command near the beginning of the shadow-cljs user guide....there is no main.html file I can find.
@factorhengineering if you continue reading the README it is telling you to create it?
@thheller I haven't read the whole thing yet, but I would have thought it would be a basic thing any project would need, so it would be created at the beginning.
the npx create-cljs-project
only generates the very bare bone project skeleton. I don't know what you are going to build. might be a node script, might be a react-native app, might be browser-based app. not all of them require html files.
I did just search for main.html, and index.html (I think that's what I meant in the first place), but I don't really see a step of creating one. ...and again, isn't it needed for CLJS?
you can use a more specific templates like the re-frame template if you like. that generates a HTML file
A react-native app wouldn't need one? Wow. OK, it does not work the way I thought it would. I thought react native just ported a standard JS-enabled webpage to mobile.
no it does not. that would be something cordova and others do.
My dream of making an app that works on web and mobile is looking ever more distant. lol A widening gulf of learning between me and it. Haha
well there is react-native-web that turns a react-native ab into a webapp but thats about all I can tell you about it. never used it myself.
Input mobile app, output webapp?? That's backwards from what I'd heard so far. OK, I wasn't going to worry about mobile just yet...focus on web...but based on that maybe I should jump right in. 😕
Will have to decide tomorrow. Too tired now. Thanks for your help. 🙂
Hello, I am curious if it is possible to get a shadow-cljs repl connected to a browser userscript.
define "browser userscript"?
like a GreaseMonkey script. (Or in my case, VionlentMonkey).
I don't know to be honest. if they can open websocket connections and eval then in theory sure you could do it
Firebase recently released a beta of their JS SDK which is designed to support tree-shaking and thus reduce bundle size. However, it doesn't seem to work!
Replicating their JS code, I've translated import {getAuth} from "firebase/auth"
as ["firebase/auth" :refer [getAuth]]
, which should import only that function. Instead it seems that everything is being imported, as it was in the previous (non-tree-shakeable) version. Is there anything else I ought to be doing here, or is this a case of Closure compiler not being able to use the same strategy as Rollup/Webpack would?
but I don't know enough about how they work at all to be sure
yes, that kind of "tree shaking" currently refers to something only js tools do, not the closure compiler
Ok, thanks!
They are pretty simple in that they more or less just inject a javascript file into a given webpage as if that webpage loaded it. Like a content script in a browser extension, except without the security restrictions. (IE. Eval works).
so in theory you can just make a normal :browser
build
and then manually inject a <script src="<http://localhost>:port/script.js">
into the page from the script
might need to tweaks some stuff like :asset-path
and :devtools-url
though
never tried it but might work
Okay, thanks! I'll look into it more and see if I can figure it out.
Does anyone know what is wrong with the following snippet?
(ns main
(:require ["@aws-sdk/client-dynamodb" :refer [DynamoDBClient ListTablesCommand]]))
(DynamoDBClient. #js {:region "eu-west-2"})
The error I am getting is:
shadow.js.shim.module$$aws_sdk$client_dynamodb.DynamoDBClient is not a constructor
I translated this from https://www.npmjs.com/package/@aws-sdk/client-dynamodb
import { DynamoDBClient, BatchExecuteStatementCommand } from "@aws-sdk/client-dynamodb";
const client = new DynamoDBClient({ region: "REGION" });
looks fine
try adding an :as
to the :require
and logging that to see what it is
also check that there are no other errors during load
aws has in the past written code that only worked with webpack, might be the case here too
can't help further though, gotta go
> also check that there are no other errors during load I didn’t restart the REPL after adding new dependency 🤦 Thank you
Hi! What would be the best way to access goog-defines (or any other setting if this is not feasible, defined in shadow-cljs.edn) in macro context to prevent generating code if a flag is set?
Answering myself: (get-in @env/*compiler* [:options :closure-defines])
Given that the project structure created by running `
npx create-cljs-project my-project
does not include any
index.html` (or a folder for CSS, as far as I can tell), how should I add it? I mean where? Somewhere in the project folder? If so, then do I need to add any pointer to where it is anywhere? And would I need to manually have it point it at wherever my main output JS file is for a given build (test vs develop vs release)?@factorhengineering the readme covers this https://github.com/thheller/shadow-cljs#quick-start css files you just put somewhere in the public folder and use link it from the HTML.
@thheller Thank you! I had been combing through the larger https://shadow-cljs.github.io/docs/UsersGuide.html but couldn't find it there. So I guess none of the automagic goodness really touches the .html file(s?) or .css file(s), and where things get put doesn't really matter other than making sure the normal linking in the index.html file (to the .css and to the .js file, where the name of the .js file would be whatever the compilation output is) is correct? Fair enough. 👍
css is not related to js in any way. they both just get included in the html and do their stuff
shadow-cljs doesn't handle generating/compiling css in any way but it does offer some basic hot reloading if you modify the file
...but the location of the .css files don't matter because shadow-cljs knows where they are based on the reference in the index.html file? OK, great. I'm probably just make a css folder under src for projects where I use CSS.
seems like you misunderstand how this works
I said "public" not src
the public folder is the folder served by the web server, so all files in that (including subdirectories) are reachable via http
so you create public/css/foo.css
and link it in your html via <link rel="stylesheet" href="/css/foo.css">
if you intend to build css using other tools that is fine, but shadow-cljs only cares about the final file in the public
folder
how it got there is not relevant as far as shadow is concerned
but all of this is basic html/css stuff, it has absolutely nothing specific to do with shadow-cljs
the path you use is also completely up to you, as long as it is in the public folder it doesn't matter
that isn't even shadow-cljs caring about it at all, its the browser needing to load it over http and only seeing what is in the public folder
or whatever other webserver you intend to use
I do understand those basics. I was just wondering where those basic files go (after getting over my initial shock that they weren't auto-generated for the project), and yes I thought maybe those basic files got acted on in some way by the tools.
well for hot-reloading it basically just watches css files in the public folder and reloads them on change, but that is the only thing shadow-cljs does regarding css files
I can't even find a public folder. I guess I need to make one myself under src?
again .. the readme covers this ...
https://github.com/dpsutton/asg-ignite-presentation here's a presentation i did that has a walkthrough and a sample app with shadow if you think that might help
Hello... would it be possible to use shadow-clj
with a backend server that runs on the JVM? I have looked through the documentation at https://shadow-cljs.github.io/docs/UsersGuide.html#dev-http but cant find a good answer to this
the public folder is not under src, it is in your project root
sure, just run it separately. shadow-cljs doesn't care which server you use and the server doesn't need to do anything special. just serve the files from disk
thanks
There's no public folder right now, so I guess I have to create it there. So in the root? OK. Scrubbing through the longer guide (Users Guide), I see lots of references to things being output to /public/js/ or /public/css/, but no reference to what the parent folder of public is, or of any files needing to be put there manually. I do see the part about setting the watchdir to public (which I guess I'm supposed to assume is my-project/public?) in order to have CSS reloading. ...but then there's a part about testing that mentions /resources/public/js/test/, which looks like a public folder not in the root. Actually the example given in the early 1.4.3 "Convensions Used" section mentions resources/public/js/ as well. Sorry just trying to wrap my head around this.
all paths mentioned are always relative to the project root, the folder your shadow-cljs.edn
is in
you incorrectly added a leading /
, you may use that but that would make it an absolute path outside your project folder
Just trying to indicate folder. I guess that's obvious. I can drop those first and last slashes.
the leading slash is very important when talking about this stuff, so it does matter whether it is there or not
Did not think it would be an absolute path without a drive or net location at the beginning, though. Maybe it's a Linux thing? It assumes /a/b/c means ~/a/b/c ?
an absolute path is an absolute path in your filesystem root
I mean (whateverdrive)/home/a/b/c
so /public/js
would be c:\public\js
on windows or just /public/js
in linux
and no /a/b/c
does NOT mean ~/a/b/c
OK, so not even home. Root of the whole drive. Got it.
@thheller if I'm serving the compiled JS files from my own server.. do you think hot reloading will still work?
In @dpsutton's presentation I see reference to folder public, which I now get is my-project/public. So I should ignore the other kind of example from the User Guide, with resources/public?
I don't think so, but I'd like to hear what you think
thats just another folder, your config decides which folders you use. those names are YOUR choice, name it whatever makes sense for you. I use public
everywhere. other people prefer resources/public
. others use dist
, target
, web
or whatever else may fit
it just works. hot-reload is not dependent on the server that served the files. that is handled by the websocket connection the compiled code opens, which will talk to the shadow-cljs watch
server directly
as far as your webserver is concerned there are just some static .js files on disk somewhere that you expose via http
alright, thanks again
OK. I'll stick with that. So at any point does that get duplicated? I have hit upon the concept of shadow-cljs having multiple targets. I would guess the index.html file in public gets used for a web release (and test?) but there is some kind of other output for, say, mobile or desktop(/server)?
that all depends on what you are building. as I said before if you build a react-native app or a node-script those will not have html files at all
OK maybe what I'm talking about only makes sense for dev vs release vs test. 1 of those uses the 'real' original index.html, and the others use some kind of auto-duplicated one? I only suggest that because I think I saw something like that in the guide. If there is only ever the one file, well I'm happy to be wrong because that would be simpler.
no, shadow-cljs will never duplicate any html for you
and again .. that entirely depends on what you are building. I pretty much always have a CLJ server generating my HTML for me, so I never have a static index.html on disk anywhere
and my dev html I have is identical to the release html in all cases
Oh right...hiccup? Yes, another thing I need to learn how to set up.
well I also have a really old rails app generating some HTML, doesn't really matter where the html is coming from
It does sound like there are multiple copies of index.html, though. If not auto-generated, then at least put in place manually for the different web targets if there are more than one.
if what you are building requires multiple html files then you'll have multiple html files yes
• I meant multiple copies, just based on the following from the User Guide:
• "Remember that the test directory will have the index.html, and a js folder." and
• "https://shadow-cljs.github.io/docs/UsersGuide.html#_generated_output_in_code_test_dir_code`:test-dir` The output includes two primary artifacts in your test-dir
folder: index.html
- If and only if there was not already an index.html
file present. By default the generated file loads the tests and runs init
in the :runner-ns
. You may edit or add a custom version that will not be overwritten.
...but I'm happy to ignore that possibility for now. I'm a long way off from doing specific test builds I would think.
Thank you for your help. As painful as it might have been for you to realize a person out there doesn't know this already by the way, I'm really glad our conversation meandered into Linux folder reference convention. I've done some things in Linux before and am still surprised that /x/y/z could ever be considered an absolute path when it doesn't mention a drive (and when it differs so little from x/y/z), like C:/x/y/z .
Maybe I'm a strange case, but I would suggest actually adding that to https://shadow-cljs.github.io/docs/UsersGuide.html#_conventions_used . (i.e. "References to folders in this book (as in many types of code (html/css/js/...) are usually relative and of the form folder-x or folder-x/subfolder-y which indicates the parent of the top folder referred to (folder-x in both cases above) is the root project folder.")
Even more helpful would be throwing in some early info on index.html, i.e. right under the npx command in https://shadow-cljs.github.io/docs/UsersGuide.html#_standalone_via_code_npm_code`npm`the text could be expanded to "This will create all the necessary basic files and you can skip the following commands. Note that index.html is not considered a basic file, and for projects which would need one (web projects), it will need to created manually. A popular practice is to also create a 'public' folder in the project root folder and create the index.html there. Any css files would also need to be created manually (or by some other method outside the scope of this book), and could be put in a new folder public/css ."
I think you have the wrong expectations here
there are far better guides/tutorials and even video courses to teach you specific things. like building a web focused thing
shadow-cljs is just a generic build tool that can do many things. I cannot possibly cover all of them, I simply do not have the time to do so
https://github.com/day8/re-frame-template for example gets you a fully running web thing out of the box
create-cljs-project
by intention is minimal and does NOT provide and target specific things
there are simply too many options, I cannot cover them all
Like I said, I fully admit I don't have the same background knowledge of many or even most other readers of that guide, but I'd like to think it was not completely crazy of me to assume that 'all the necessary basic files' for a CLJS project would include index.html and maybe even a single .css file. 😉
I mean I know that was wrong now, but... Haha.
there is also https://github.com/filipesilva/create-cljs-app which maybe better suited for your needs, that also generates much more web centric stuff (including html and css 😉)
Your first link scares me a bit, what with needing leiningen (I thought I heard using shadow-cljs would mean not needing to also use leiningen) and node.js (I thought...still think actually...node.js was for server-side/desktop, but maybe it's there because it generates front-end and back-end.
you already used node.js when you executed npx create-cljs-project
npx
is part of npm
which comes with node
you don't need to use leiningen, but some people prefer to do so. so some templates use it, many also use deps.edn. those are all valid options, as I said ... impossible for me to cover them all
Same with re-frame, actually. I was trying to minimize the number of new things I need to learn at once (WSL2 + Linux CLI + Doom Emacs (vi) + CLJS + <some build tool, which I chose to be shadow-cljs based on recommendations based on it being able to handle a lot>), but I accept your challenge of adding re-frame to that soon. 😎 I'll lean toward deps.edn over leiningen, though, just since it seems simple (just an actual file).
I'll dive into your second link even sooner, though. Thanks again.