Fork me on GitHub
#shadow-cljs
<
2023-02-27
>
pyr07:02:30

Hello everyone! When starting the development server in shadow-cljs, index.html is served but access to the / url does not resolve to /index.html, yielding a 500 error (and an exception log coming from shadow-undertow java.lang.ClassCastException: class clojure.lang.Keyword cannot be cast to class java.lang.String coming from set-headers meaning that something tried to supply headers as keywords). Nothing major but I couldn't find the reason for this small annoyance, if anyone can share a pointer I'd happily do the necessary patching.

thheller07:02:48

what is your config? :dev-http? any custom handler?

thheller07:02:10

and what is the full stacktrace? that should give you a hint where it is coming from

pyr07:02:08

I have an additional handler but if I remove it the problem remains (tried that already). Here is the full stack trace: https://gist.github.com/pyr/76bc334e12ab4d97dac753b33289391a

pyr07:02:01

I'm on 2.21.0 and cljs 1.11.60

pyr07:02:51

The above is with the handler sorry

thheller07:02:18

what is this handler doing? I mean you are likely setting {:status 200 {:headers {:foo "whatever"}} :body ...} in it? or maybe some middleware it uses?

thheller07:02:31

headers are supposed to be strings, so thats why it blows up

thheller07:02:14

guess the handlers is done at this point, so thats why its not showing up in the stacktrace

pyr07:02:25

OK yes this is likely happening on the error path. I'll fix that. Regardless, without the handler I still get a 404 on /, is there a way to tell shadow-undertow to look for index.html in that case?

thheller07:02:54

without seeing what your actual config is I cannot answer that

thheller07:02:43

the default will serve index.html. say :dev-http {3000 "public"} accessing localhost:3000 will look for public/index.html

pyr07:02:17

This gives me "Not found" for /

thheller07:02:17

the push-state handler will do that though, so if you have a custom handler it is responsible for serving that

pyr07:02:56

understood, so the fact that used a map push-state didn't get used, it's then up to my API to perform the redirect

thheller07:02:59

maybe the trailing / is confusing it?

thheller07:02:33

yes, in older versions the presence of index.html always bypassed the handler

thheller07:02:06

if you want that behavior back you can set :use-index-files true in the server config

thheller07:02:35

as in :dev-http {3000 {:root "public" :use-index-files true :handler your.thing/handler}}

thheller07:02:57

only really make sense if you have a custom handler, the default should behave as expected

pyr07:02:03

understood

thheller07:02:06

:dev-http {8000 {:root "public/"}} should server public/index.html on localhost:8000

thheller07:02:21

but it might be OS/FS dependent whether it does. maybe needs to be :dev-http {8000 {:root "public"}}

pyr07:02:25

:use-index-files is what I was looking for, thank you

pyr07:02:39

I was confused by push-state, since I was testing with curl, I still so not-found on / whereas without my handler the browser would indeed see its state pushed to /index.html

pyr08:02:05

but :use-index-files works, so unless it is slated for removal I'll keep using that

thheller08:02:09

if you write a custom handler you can call (shadow.http.push-state/handle req) if you own handler is not interested tohandle it

thheller08:02:42

or use your own server altogether if you want more control 😉

thheller08:02:56

:dev-http is not required for any development features (eg. REPL/hot-reload)

thheller08:02:10

but yes :use-index-files will stay

pyr08:02:19

sorry for the mixup in any case, and thanks for the help. I've got plenty of options now 🙂

Maris16:02:54

var Select = (0, _stateManager.default)(_Select.default); Select.Async = _Async.default; Select.AsyncCreatable = _AsyncCreatable.default; Select.Creatable = _Creatable.default; Select.SelectBase = _Select.default; Select.createFilter = _filters.createFilter; Select.components = _index.components; Select.mergeStyles = _styles.mergeStyles; Select.defaultTheme = _theme.defaultTheme; var _default = Select; exports.default = _default;

Maris16:02:16

What should I type in CLJS to access Select?

Maris16:02:38

react-select/Select nil

Maris16:02:03

It is nil in the REPL ^ 😢

Maris16:02:33

(:require
   ["react-select" :as react-select]

thheller16:02:09

@maris.orbidans see the import translation table here https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages. I'm guessing the JS example is

import Select from "react-select";
then it would be (:require ["react-select$default" :as Select])

👍 4
Maris16:02:05

What about Select.Creatable ?

Maris16:02:15

I want to use ^ as well

thheller16:02:48

see the docs. :as is just a namespace alias after that. so Select/Creatable works or :refer (Creatable) also works

👍 2
Maris17:02:25

I tried to load jquery ["jquery/src/jquery.js"]

Maris17:02:32

ReferenceError: define is not defined
    at shadow$provide.module$node_modules$jquery$src$jquery (jquery.js:2:1)
    at shadow.js.jsRequire (js.js:66:18)

Maris17:02:38

Maybe require should be different?

thheller17:02:05

yes, just ["jquery" :as jq]. always consult the library docs and look at the conversion examples I linked above

Maris17:02:02

ok, it seems to work