bhauman / lein-figwheel

Figwheel builds your ClojureScript code and hot loads it into the browser as you are coding!
Eclipse Public License 1.0
2.88k stars 210 forks source link

figwheel-sidecar breaks :websocket-host #683

Open vincent-dm opened 6 years ago

vincent-dm commented 6 years ago

Hi,

I noticed that the :websocket-host config param is ignored when I load figwheel-sidecar in my (dev) dependencies (and thus the defaultlocalhost value is used instead of what's in my config).

I'm not sure if this a bug or intentional behavior due to some inherent property of sidecar. But even then, some warning in the docs or on runtime could spare people a lot of time :-) If changing the docs is the solution, I'm willing to do a PR.

(FYI: my use case is that I want to run Figwheel from my Cursive REPL (because it has a nicer editor) and hot-reload my app on a smartphone on the local network. I can currently do either of these things separately, but the behavior described above prevents me from doing both at the same time.)

bhauman commented 6 years ago

I don't completely understand the situation you are describing here.

How are you starting figwheel?

Is the :websocket-host figwheel config changing? and more specifically what specific thing is causing it to change?

vincent-dm commented 6 years ago

Ok, I updated my initial text for clarity.

The problem is that the value of the :websocket-host config param in project.clj seems to be ignored when I load figwheel-sidecar in my (dev) dependencies. I can put any (valid) value there, but the browser will always try to make a websocket connection with localhost.

The config syntax itself is still validated though: when I move the param to an invalid block, I get the expected error message, but as soon as I set it in the valid place, it is just ignored.

FYI: I start it using lein figwheel, but it's the same when I explicitly add dev as arg.

When I remove the figwheel-sidecar dependency, the :websocket-host value is read and it behaves as expected.

My project.clj is as follows (this one relies on the latest -SNAPSHOT release, but I also have it with latest stable):

(defproject
  foo/bar "1.0.0"
  :license "Proprietary"
  :url "https://www.foo.bar

  :dependencies [[org.clojure/clojure "1.9.0"]
                 [org.clojure/clojurescript "1.10.238"]

                 ; Fix conflicts on 'lein deps'
                 [org.clojure/tools.nrepl "0.2.13"]

                 [reagent "0.8.0-rc1" :exclusions [cljsjs/react cljsjs/react-dom]]
                 [cljsjs/react "16.3.0-1"]
                 [cljsjs/react-dom "16.3.0-1"]
                 [binaryage/oops "0.5.8"]
                 [prismatic/schema "1.1.9"]
                 [frankiesardo/linked "1.3.0"]]

  :pedantic? :abort

  :clean-targets ^{:protect false} ["target" "resources/public/js/" "resources/private/js/"]

  :plugins [[lein-cljsbuild "1.1.7"]
            [lein-figwheel "0.5.16-SNAPSHOT" :exclusions [org.clojure/clojure]]]

  :profiles {:dev  {:source-paths ["src" "dev"]
                    :dependencies [[binaryage/devtools "0.9.10"]
                                   [cider/piggieback "0.3.1"]
                                   [figwheel-sidecar "0.5.16-SNAPSHOT"]
                                   [devcards "0.2.5-SNAPSHOT"]]}}

  :repl-options {:nrepl-middleware [cider.piggieback/wrap-cljs-repl]}

  :figwheel {:css-dirs ["resources/public/css"]}

  :cljsbuild {:builds [{:id           "dev"
                        :source-paths ["src"]
                        :compiler     {:main                 app.core
                                       :asset-path           "/js/compiled/frontend/out"
                                       :output-to            "resources/public/js/compiled/frontend.js"
                                       :output-dir           "resources/public/js/compiled/frontend/out"
                                       :optimizations        :none

                                       :recompile-dependents false
                                       :parallel-build       true

                                       :compiler-stats       true
                                       :preloads             [devtools.preload]}
                        :figwheel     {:websocket-host :js-client-host
                                       :on-jsload     "app.core/on-jsload"
                                       :before-jsload "app.core/before-jsload"}}

                       {:id           "devcards"
                        :source-paths ["src-cards" "src"]
                        :compiler     {:main                 "cards.start-ui"
                                       :asset-path           "js/compiled/cards/out"
                                       :output-to            "resources/public/js/compiled/cards.js"
                                       :output-dir           "resources/public/js/compiled/cards/out"

                                       :recompile-dependents false
                                       :parallel-build       true
                                       :compiler-stats       true
                                       :preloads             [devtools.preload]}
                        :figwheel     {:devcards true}}]})
dous commented 6 years ago

I can reproduce the bug where :websocket-host seems to be ignored. I tried to follow the documentation here https://github.com/bhauman/lein-figwheel/blob/master/README.md#client-side-configuration-options and when setting :websocket-host or :websocket-url to a value other than "localhost", the host is still "localhost" in resources/public/js/compiled/out/figwheel/client.js after re-running lein figwheel.

I'm also trying to hot-reload my app on a separate device on the network. Browser tabs on the machine where I'm running figwheel hot-reloads fine while on the other device, it does not.

tkamat commented 5 years ago

I can also reproduce this bug, I am trying to run figwheel on chrome in chromeos, using the new linux containers, but changing the :websocket-host doesn't seem to have any effect. Figwheel runs fine on the local firefox, but it doesn't change the host from localhost.

terjedahl commented 5 years ago

So I struggled with the same problem, and finally found the cause: The generated JS-files are cached in $HOME/.cljs/.aot_cache/, and are reused when you restart figwheel. And since the websocket-url is embedded in the JS, and the file isn't updated when you change the ':server-port', ':websocket-host' et al, the old url persists across restarts.

My workaround is a simple rm -fR ~/.cljs/.aot_cache as part of my figwheel launch command, but I imagine there is some way to update the cached file from figwheel when a relevant value is altered.

The solution is to do:

:compiler {:aot-cache false
           ,,,}
arkRedM commented 4 years ago

@terjedahl
I cleared aot_cache and applied the suggested changes, there seems to be no effect. Your explanation is suffice but is there any missing step involved?

Any update on this? Has someone fixed it?

anghene commented 4 years ago

I have the same problem when running two different builds. I have all configs in my project.clj (didn;t want separate edn files except for some variables i use in dev). I start two builds app - for the frontend , dash for the dashboard, and both of them are making figwheel WS requests to ws://localhost:3449/figwheel-ws/name-of-build even though i specifically added :websocket-url "ws://localhost:3449/figwheel-ws" to both builds. Even if I change any of them to append name-of-build like this: :websocket-url "ws://localhost:3449/figwheel-ws/dash" for what seems to be called on WS when I access dashboard zone, it is completely ignored. the rebel readline won't connect because apparently my lein figwheel starts a websocket on Figwheel: Starting server at http://0.0.0.0:3449. No matter how much i want to make them both connect on the same ws url, I can't seem to find a solution. Above solution proposal doesn't work (no aot-cache).

   :project/dev  {:jvm-opts ["-Dconf=dev-config.edn"]
                  :figwheel {:builds-to-start ["app" "dash"]}
                  :dependencies [....
                                 **[figwheel-sidecar "0.5.19"]** <----- seems to cause problems overriding ws url
                                 ... ]]
                  :plugins      [...
                                 [lein-figwheel "0.5.19"]]
                  :cljsbuild {:builds
                              {:app
                               {:figwheel {:on-jsload "on-js-reload"
                                                :websocket-url "ws://localhost:3449/figwheel-ws"}
                                :source-paths ["src/cljs" "src/cljc" "env/dev/cljs"]
                                :compiler
                                {:main "frontend.app"
                                 :asset-path "/js/out-app"
                                 :output-to "resources/public/js/app.js"
                                 :output-dir "resources/public/js/out-app"
                                 :source-map true
                                 :optimizations :none
                                 :pretty-print true}}
                               :dash
                               {:figwheel {:on-jsload "ridemanager.dash/refresh"
                                           :websocket-url "ws://localhost:3449/figwheel-ws"} **<--- compiled js code will always make WS requests to "ws://localhost:3449/figwheel-ws/dash" for some reason**
                                :source-paths ["src/cljs" "src/cljc" "env/dev/cljs"]
                                :compiler
                                {:main "frontend.dash"
                                 :asset-path "/js/out-dash"
                                 :output-to "resources/public/js/dash.js"
                                 :output-dir "resources/public/js/out-dash"
                                 :source-map true
                                 :optimizations :none
                                 :pretty-print true}}}}