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 208 forks source link

figwheel-sidecar.repl-api does not run hooks #583

Open raxod502 opened 7 years ago

raxod502 commented 7 years ago

I have my Figwheel configured as follows:

  :figwheel {:destroy labelizer.server/stop-server
             :init labelizer.server/start-server}

This means that when I start lein figwheel, it starts my Ring server instead of its own server:

% lein clean && lein figwheel
Figwheel: Cutting some fruit, just a sec ...
Figwheel: Validating the configuration found in project.clj
Figwheel: Configuration Valid :)
Figwheel: calling your :init function -  #'labelizer.server/start-server
Server running on port 3000.
Figwheel: Starting server at http://0.0.0.0:3449
Figwheel: Watching build - app
Figwheel: Cleaning build - app
Compiling "target/resources/dev/public/js/main.js" from ["src/cljs"]...
Successfully compiled "target/resources/dev/public/js/main.js" in 7.117 seconds.
Launching ClojureScript REPL for build: app
Figwheel Controls:
          (stop-autobuild)                ;; stops Figwheel autobuilder
          (start-autobuild [id ...])      ;; starts autobuilder focused on optional ids
          (switch-to-build id ...)        ;; switches autobuilder to different build
          (reset-autobuild)               ;; stops, cleans, and starts autobuilder
          (reload-config)                 ;; reloads build config and resets autobuild
          (build-once [id ...])           ;; builds source one time
          (clean-builds [id ..])          ;; deletes compiled cljs target files
          (print-config [id ...])         ;; prints out build configurations
          (fig-status)                    ;; displays current state of system
          (figwheel.client/set-autoload false)    ;; will turn autoloading off
          (figwheel.client/set-repl-pprint false) ;; will turn pretty printing off
  Switch REPL build focus:
          :cljs/quit                      ;; allows you to switch REPL to another build
    Docs: (doc function-name-here)
    Exit: Control+C or :cljs/quit
 Results: Stored in vars *1, *2, *3, *e holds last exception object
Prompt will show when Figwheel connects to your application
To quit, type: :cljs/quit
app:cljs.user=>

Note especially the line

Server running on port 3000.

which is printed by my :init function.

Now on the other hand, when I use figwheel-sidecar.repl-api to start my CLJS REPL, as advised on the wiki, I get this:

% lein clean && lein repl
nREPL server started on port 51946 on host 127.0.0.1 - nrepl://127.0.0.1:51946
REPL-y 0.3.7, nREPL 0.2.13
Clojure 1.8.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_112-b16
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

labelizer.server=> (use 'figwheel-sidecar.repl-api)
nil
labelizer.server=> (start-figwheel!)
Figwheel: Starting server at http://0.0.0.0:3449
Figwheel: Watching build - app
Figwheel: Cleaning build - app
Compiling "target/resources/dev/public/js/main.js" from ["src/cljs"]...
Successfully compiled "target/resources/dev/public/js/main.js" in 6.442 seconds.
nil
labelizer.server=>

Notice the conspicuous failure to run my :init function. Instead, Figwheel has started its own server.

You can see the full project here.

raxod502 commented 7 years ago

In particular, the examples/separate-server project exhibits the same behavior. If you launch Figwheel from figwheel-sidecar.repl-api, then a page is opened pointing at localhost:3000 which of course doesn't work since the server hasn't been started.

bhauman commented 7 years ago

The :init and :destroy features are only available from Leinigen.

https://github.com/bhauman/lein-figwheel/blob/master/sidecar/src/figwheel_sidecar/schemas/config.clj#L84

The reason for this is that it is trivial to call your own start and stop f unctions directly from your own script. This feature is intended for the Leinigen environment where it is very difficult to compose functionality.

On Sat, Jul 22, 2017 at 1:26 PM, Radon Rosborough notifications@github.com wrote:

In particular, the examples/separate-server project exhibits the same behavior. If you launch Figwheel from figwheel-sidecar.repl-api, then a page is opened pointing at localhost:3000 which of course doesn't work since the server hasn't been started.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/bhauman/lein-figwheel/issues/583#issuecomment-317198162, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAKQPBrLbKeWlyw5f7ymAUx61GqPg0dks5sQjDKgaJpZM4OgEag .

raxod502 commented 7 years ago

That makes sense. Perhaps I should elaborate on my use case. In CIDER, you can launch a fully integrated ClojureScript REPL by specifying a form to be evaluated to turn a Clojure REPL into a ClojureScript REPL. For example, these are the built-in forms. I'm using the Figwheel-sidecar one.

So this means that I can launch a ClojureScript REPL for any project simply by pressing C-c M-J. But it doesn't work if I rely on :init and :destroy, since those hooks aren't run by figwheel-sidecar.repl-api!

I understand for most use cases (scripting…), it's trivial to call my hook functions manually. But unfortunately it's not as straightforward to do this from Emacs—I don't want to hardcode my hook functions for every project.

I could implement reading the project.clj and extracting the hook functions, but figwheel-sidecar already implements this logic. Is there a straightforward way that I can invoke the hook functions defined in the project.clj manually? (I totally understand that you wouldn't want to change the default behavior though.)