Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blank page due to conflicting shadow-cljs >= 2.19.9 and wrap-resource (ring) call #17

Open
formsandlines opened this issue Oct 11, 2022 · 7 comments

Comments

@formsandlines
Copy link

For some reason, the template lein new reagent-frontend <name> +shadow-cljs breaks for me if the shadow-cljs dependency in package.json is above version 2.19.8.

npx shadow-cljs watch app will only render the page when I remove :handler user/app from the shadow-cljs.edn file. I was looking through the changes in https://github.com/thheller/shadow-cljs/blob/6d72ac7e09a1e153fa05498f19fa8dee34bd2474/CHANGELOG.md but I can’t isolate what may be causing this (maybe a dependency bump).

Of course, this relates to the form (def app (wrap-resource identity "public")) in src/user.clj. Replacing the call to wrap-resource with the shadow-cljs default shadow.http.push-state/handle fixes it, so I am quite sure that it has something to do with the ring-core dependency (1.9.5 in my case) that may conflict somehow with shadow-cljs (>= 2.19.9).

But even after reinstalling ring and shadow-cljs in my local Maven repo it will just render an empty page, with an empty <head> and <body> tag, no error messages in the terminal or browser console.

It happens with Reagent 1.1.0 as well as 1.1.1.

@yogthos
Copy link
Member

yogthos commented Oct 11, 2022

Any chance you could do a pr for the fix? :)

@eastack
Copy link

eastack commented Oct 27, 2022

It feels like it is probably related to the version upgrade of shadow-undertow.

Related commits:
shadow-cljs (dep bumps)
shadow-undertow (change file/classpath handlers to not use index files by default)

Eventually I temporarily solved the problem by adding :use-index-files true directly to the code in shadow-cljs . My English is very bad. And clojure has only been learned for a few days. If you have time, maybe you can help open an issue on shadow-cljs. thank you very much.

image

@yogthos
Copy link
Member

yogthos commented Oct 29, 2022

Thanks for the explanation of the problem. I'll open an issue for it on shadow-cljs repo.

@yogthos
Copy link
Member

yogthos commented Oct 29, 2022

here's the issue to track thheller/shadow-cljs#1058

@thheller
Copy link

thheller commented Oct 29, 2022

This is a problem with the generated code.

(def app (wrap-resource identity "public"))

Previously I guess this was relying on broken behavior, where the presence of an index.html file would prevent the request from ever reaching the configured handler. This is now fixed, and the handler is reached properly. However wrap-resource is used to look up sources on the classpath. The project root however is not on the classpath, so it won't find the public/index.html resource.

My suggested fix here would be to remove this handler entirely. This custom handler does nothing that the built-in :dev-http doesn't already do.

Change the generated shadow-cljs.edn

:dev-http     {3000 {:root    "public"
                     :handler user/app}}

and remove the ring/handler references from the generated user.clj.

Instead then just generate this in shadow-cljs.edn

:dev-http {3000 "public"}

This will serve all static files from the public directory properly. The default handler will also serve the index.html properly. If the desire is to also serve resources from the actual classpath (eg. from jars) you may change it to

:dev-http {3000 ["public" "classpath:public"]}

This will first look in the local public directory and then search the classpath (as wrap-resource would). If none are found the push-state default handler will take over. This is to enable client-side routes like /foo/bar working on a page refresh.

If you must have the custom handler then you must also adjust all the other path accordingly, so that the public dir is actually on the classpath. So, moving it to resources/public and adding resources to the :source-paths. This is all no different than a normal CLJ server setup.

My strong recommendation is to remove this handler though. If a custom handler is actually required, a full custom ring server should be used instead. :dev-http is absolutely optional and provides no functionality that would be required for hot-reload or REPL tasks, they'll work with any webserver.

Edit: Besides the above mentioned problems what is (wrap-resource identity "public") actually intended to be? The identity part? A ring handler just returning the request is not valid and can never produce a proper response?

@formsandlines
Copy link
Author

Thanks for following up on this. Removing the handler references also fixed it for me, but I wasn’t sure what exactly it does for the template to attempt a pr, having almost no experience with server stuff whatsoever.

@yogthos
Copy link
Member

yogthos commented Oct 29, 2022

@thheller thanks for the explanation. Removing custom handler is working as intended on my end as well. And don't actually recall what the point of wrapping identity was. That just looks like a bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants