shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
Ronny Li 2021-06-03T02:36:48.324200Z

Hi everyone, does shadow-cljs handle URL rewriting to support deep-linking into a single-page app? We are hosted on firebase and to perform rewrites we just need to do the following (Note that we actually have two pages. Hopefully that's not an obstacle):

"rewrites": [
      {
        "source": "/",
        "destination": "/index.html"
      }, {
        "source": "**",
        "destination": "/trade.html"
      }
    ]
So http://www.mysite.com/foo/bar rewrites to /trade.html on firebase but not in localhost. Any suggestions for how to fix this would be greatly appreciated!

thheller 2021-06-03T06:52:12.324700Z

just use a the local firebase development http server. IIRC it has one? don't need to use the shadow-cljs http server for this.

Ronny Li 2021-06-03T09:56:40.329200Z

Thanks for the the reply Thomas. My understanding is that the https://firebase.google.com/docs/hosting/test-preview-deploy#test-locally doesn't support hot reloading? Step 4 of https://firebase.google.com/docs/hosting/test-preview-deploy#test-locally says "To update the local URL with changes, refresh your browser."

Ronny Li 2021-06-03T09:58:33.329400Z

but you're totally right that I'm able to test deep-linking when I use firebase emulators:start as opposed to

shadow-cljs watch app

thheller 2021-06-03T10:00:21.329600Z

those two are completely separate and the HTTP server you use has nothing to do with hot-reloading. that is separate.

Ronny Li 2021-06-03T11:08:12.330700Z

oooh gotcha so I'm supposed to run both at the same time. Thank you!

thheller 2021-06-03T11:08:44.330900Z

yes

2021-06-03T09:49:31.329100Z

Is there a way to bundle eg. binary images along with an :npm-module build? Such that I can get a URL to use in eg. an [:img {:src image-url}]? I'm thinking of something like the Webpack(?) bundler(?) that lets one import { default as myImageUrl } from './my-image.png'; in Javascript.

Ronny Li 2021-06-03T09:56:40.329200Z

Thanks for the the reply Thomas. My understanding is that the https://firebase.google.com/docs/hosting/test-preview-deploy#test-locally doesn't support hot reloading? Step 4 of https://firebase.google.com/docs/hosting/test-preview-deploy#test-locally says "To update the local URL with changes, refresh your browser."

Ronny Li 2021-06-03T09:58:33.329400Z

but you're totally right that I'm able to test deep-linking when I use firebase emulators:start as opposed to

shadow-cljs watch app

thheller 2021-06-03T10:00:21.329600Z

those two are completely separate and the HTTP server you use has nothing to do with hot-reloading. that is separate.

thheller 2021-06-03T10:01:12.329900Z

no

2021-06-03T10:34:50.330600Z

okay, that's what I thought thanks πŸ™‚

Ronny Li 2021-06-03T11:08:12.330700Z

oooh gotcha so I'm supposed to run both at the same time. Thank you!

thheller 2021-06-03T11:08:44.330900Z

yes

ikitommi 2021-06-03T11:42:38.331900Z

is there a shadow + StoryBook example around there? the link in Clojureverse seems dead: https://github.com/shadow-cljs/examples/tree/master/cljs-storybook

rberger 2021-06-05T17:03:46.387300Z

I for one would love a :target :storybook. Personally I think it would be a game changer in terms of making Clojurescript more popular.

rberger 2021-06-05T17:05:45.389400Z

Also @shaolang wrote something up on his recent experience with it https://shaolang.github.io/posts/2021-02-14-storybook.js-with-shadow-cljs/

thheller 2021-06-05T17:06:16.389900Z

personally I'd much rather have some CLJS based. storybook doesn't look that special to me?

rberger 2021-06-05T17:07:36.390600Z

It's an ecosystem that would be nice to be part of. And there is no CLJS equivalent that I have found. Wish there were!

thheller 2021-06-05T17:18:06.391600Z

looks fine for me from the config side. not sure what else :target :storybook could make easier?

thheller 2021-06-05T17:18:39.392200Z

FWIW :target :npm-module also supports :ns-regexp "stories$" so you don't have to list all :entries manually

thheller 2021-06-05T17:19:16.392400Z

{:target      :npm-module
 :ns-regexp   "stories$"
 :output-dir  "public/js/stories"}

rberger 2021-06-05T17:22:58.393200Z

Well you suggested :target :storybook 😁 Sounded good to me. I have seen a few stabs at getting a minimal usage, I haven't had a chance to really dive into it yet. But my interest is to use it as a way to document our internal UI Components and evolve to a design system. Ideally with the ability to leverage other things going on in the Storybook world (which may or may not really be possible if there are a lot of assumptions about having JS code be the main underlying "glue"

thheller 2021-06-05T17:26:06.393800Z

yeah but the blogpost you linked looks pretty optimal to me. not sure what else a :target :storybook could do. there could be one if it was more complicated but it doesn't seem to be. I don't use storybook so no clue where the problems are

rberger 2021-06-05T17:27:06.394Z

Yes, will need to dive into it. Wish I had more time to explore meta tools for CLJS UI building. Maybe someday

alexdavis 2021-06-03T11:53:48.332Z

https://github.com/lilactown/storybook-cljs this is reasonably recent

ikitommi 2021-06-03T12:09:14.332300Z

thanks!

thheller 2021-06-03T13:40:46.335100Z

there could be a :target :storybook that outputs everything exactly in the format storybook wants but so far not too many people use storybook it seems

2021-06-03T17:37:34.335800Z

why is the file argument to load-file must be in classpath? https://github.com/thheller/shadow-cljs/blob/e6c7d36dc4a870c0b64286e0b590e69c06c63d43/src/main/shadow/cljs/repl.clj#L296

2021-06-03T17:39:10.336700Z

what does it take to remove that constraint? I suppose it's connected to other part of the code base?

thheller 2021-06-03T17:40:09.337700Z

because thats generally what you want for a "build tool", repeatable builds are the focus. so accessing stuff outside the classpath is generally not allowed

thheller 2021-06-03T17:40:58.338300Z

why do you care? I mean what files are you trying to load that aren't on the classpath?

2021-06-03T17:42:00.339300Z

I asked because I'm using lispy-mode in emacs (an alternate to paredit) which load some "middleware" which is just a cljs file packaged with lispy-mode itself

2021-06-03T17:43:08.340700Z

currently lispy-mode can't work with shadow because it use cider to load the said cljs file when starting up lispy

2021-06-03T17:43:48.341200Z

and I see repl-load-file* thow exception that the file is not in class path

thheller 2021-06-03T17:43:59.341400Z

hmm yeah thats a problem

2021-06-03T17:45:24.342300Z

so what does it take to fix? I suppose it may break the api or make some errors become uncaught?

thheller 2021-06-03T17:45:58.342700Z

replacing this throw with an impl that supports files outside the classpath https://github.com/thheller/shadow-cljs/blob/e6c7d36dc4a870c0b64286e0b590e69c06c63d43/src/main/shadow/cljs/repl.clj#L294

thheller 2021-06-03T17:46:26.343300Z

basically the same as the impl below that, just without all the classpath references

thheller 2021-06-03T17:47:24.343900Z

will be kinda hard without understanding how all of it works internally πŸ˜›

2021-06-04T10:06:40.370500Z

this is hard indeed with all the internals πŸ˜„

thheller 2021-06-04T12:29:24.370700Z

I went with a slightly different strategy so that it doesn't matter whether the file is on the classpath at all, no difference in code executed

thheller 2021-06-04T12:30:17.371Z

I wanna look into something else first but I'll try to make a release later today

1🀘
thheller 2021-06-04T14:11:16.372Z

try 2.14.3

2021-06-04T14:11:58.372200Z

great. Many thanks

thheller 2021-06-03T17:47:46.344700Z

feel free to open an issue about this. can't get to it right now but maybe over the weekend

2021-06-03T17:48:53.345400Z

yes, I will. I'm trying to make a PR anyway...

2021-06-03T17:49:43.346300Z

thank you very much

ikitommi 2021-06-03T18:20:17.346400Z

might see more adoption if the integration would be that trivial?

ikitommi 2021-06-03T18:23:15.346600Z

the example doesn’t work anymore:

TypeError: Cannot read property 'CLOSURE_UNCOMPILED_DEFINES' of undefined

thheller 2021-06-03T18:26:53.346800Z

hmm yeah storybook changes a lot. kinda switches how everythingthing works every version. haven't looked at it recently.