How to handle the new HTTP configuration for shadow-cljs? - build

I have been using Clojure, ClojureScript, lein, shadow-cljs, Emacs,
and CIDER to work on a Clojure/ClojureScript dynamic web app project.
Usually, I build the project by executing the command
cider-jack-in-cljs in Emacs, choosing shadow-cljs, then shadow
for REPL type, and, finally, app for the building option.
Things were working fine. I was used to watching changes on the UI on
localhost:3005.
But, an answer from a previous question indicated that the
project was using an old (and deprecated) HTTP configuration for
shadow-cljs.
On shadow-cljs.edn we had:
{:source-paths ["src" "dev"]
:dependencies ...omitted..
:nrepl {:port 8230
:nrepl-middleware [dirac.nrepl/middleware]}
:builds {:app {
:devtools {:after-load app.core/main
:http-root "public"
:http-port 3005
:preloads [shadow.cljs.devtools.client.hud
day8.re-frame-10x.preload
dirac.runtime.preload
devtools.preload]}
}}}}}
After the build was complete, I would see the live application on
localhost:3005. The mini-buffer would direct me to see the
rendered page on the browser.
On shadow-cljs.edn, now, we have:
{:source-paths ["src" "dev"]
:dependencies ...omitted..
:nrepl {:port 8230
:nrepl-middleware [dirac.nrepl/middleware]}
:builds {:app {
:devtools {:after-load app.core/main
:preloads [shadow.cljs.devtools.client.hud
day8.re-frame-10x.preload
dirac.runtime.preload
devtools.preload]}
:dev-http {3005 "public"}
}}}}}
However, the workflow for development is different.
Emacs mini-buffer redirects me on the browser to a different address:
http://localhost:9630/dashboard
Also, old localhost:3005 does not work, even though it is mentioned
on :dev-http {3005 "public"}.
1 - What is the new workflow to change the code and see the changes?
2 - Why is port localhost:3005 not working anymore even though it is mentioned in the source code?
3 - What is the purpose of the dashboard?

:dev-http is a top-level config. It is not part of a build config. It needs to sit at the same level as :nrepl and :builds.
{:source-paths ["src" "dev"]
:dependencies ...omitted..
:nrepl {:port 8230
:nrepl-middleware [dirac.nrepl/middleware]}
:dev-http {3005 "public"}
:builds
{:app
{...
:devtools
{:after-load app.core/main
:preloads
[day8.re-frame-10x.preload
dirac.runtime.preload
devtools.preload]}}}}}}

Related

How to create a multi-page application with Figwheel and Leiningen?

I have a simple Figwheel application which is built with Leiningen.
I want to have multiple pages in it:
index.html should use the code from hello-figwheel.core.
page2.html should use the code from hello-figwheel.page2
I assume I have to somehow modify the project.clj file:
:compiler {:main hello-figwheel.core
:asset-path "js/compiled/out"
:output-to "resources/public/js/compiled/hello_figwheel.js"
:output-dir "resources/public/js/compiled/out"
:source-map-timestamp true
;; To console.log CLJS data-structures make sure you enable devtools in Chrome
;; https://github.com/binaryage/cljs-devtools
:preloads [devtools.preload]}}
How can I tell Leiningen to compile
hello-figwheel.core to resources/public/js/compiled/hello_figwheel.js and
hello-figwheel.page2 to resources/public/js/compiled/page2.js?
There is a similar question. The difference to this one is that Leiningen is used to run Figwheel.
Update 1: I added the following to the project.clj file:
{
:id "page2"
:source-paths ["src"]
:compiler {
:output-dir "resources/public/js/compiled/page2"
:output-to "resources/public/js/compiled/page2/main.js"
:main hello-figwheel.page2
:asset-path "js/compiled/out"
:source-map-timestamp true
;; To console.log CLJS data-structures make sure you enable devtools in Chrome
;; https://github.com/binaryage/cljs-devtools
:preloads [devtools.preload]}
:figwheel {:on-jsload "hello-figwheel.page2/on-js-reload"
;; :open-urls will pop open your application
;; in the default browser once Figwheel has
;; started and compiled your application.
;; Comment this out once it no longer serves you.
:open-urls ["http://localhost:3449/page2.html"]}
}
When I run lein figwheel, the REPL is unable to connect to my web application:
It says Prompt will show when Figwheel connects to your application, but it never happens.
Also, if I open http://localhost:3449/page2.html in the browser, update page2.cljs, and refresh the page in the browser, the changes are not visible there.

Kaocha-midje setup

We have a load of midje tests setup for Clojure, they currently work with lein midje.
We want to use Kaocha-midje, and then the rest of kaocha, but cannot get any tests to be found using Kaocha.type/midje.
Heres the project.clj add-ins:
:profiles {:dev {:dependencies [[midje "1.9.9"]
[lambdaisland/kaocha "1.0.861"]
[lambdaisland/kaocha-midje "0.0-5"]}}
:aliases {"kaocha" ["run" "-m" "kaocha.runner"]}
There is also the test.edn file
{:tests [
{:type :kaocha.type/midje
:id :midje
:source-paths ["src"]
:test-paths ["test/unit/directory/path/example_midje_test.clj"]}
]
:kaocha/fail-fast? false
:kaocha/color? true
:kaocha.plugin.randomize/randomize? false
:kaocha/reporter [kaocha.report/dots]
:kaocha/plugins [:kaocha.plugin/randomize
:kaocha.plugin/filter
:kaocha.plugin/capture-output]}
example_midje_test.clj is the example from https://github.com/lambdaisland/kaocha-midje/blob/master/test/midjetest/the_test.clj
but I have also tried one of our existing tests, and also tried test/unit so it can find them all, but it gives Spec errors, but none of our tests currently fail.
This is the error output for the test/unit test-path
WARNING: No tests were found, make sure :test-paths and :ns-patterns are configured correctly in tests.edn.
Also posted here https://github.com/lambdaisland/kaocha/issues/230
Which said the midje kaocha is experimental at best and suggested moving to something else.

How to change Lein's Clojure default version outside of a project directory?

This is asking for help regarding the same question as How to change Clojure or Lein's Clojure default version?
but is not an answer to that question. Should I have nevertheless have written it as an answer under that thread?
Specifying a Clojure version to be used when the "(lein repl)" command is issued outside of a project directory seems to be a natural thing to want. Of course there may be good design reasons for not allowing it, but do you think an error message like the following,
to be displayed when Leiningen detects that the ~/.lein/profiles.clj (or other relevant profile files) specify a different Clojure version from the one hard coded into Leiningen,
would be a good idea?
"specifying the Clojure version to be used with certain software, such as tools.nrepl and clojure-complete, is only allowed when this command is issued within a project directory"
A lot of people apparently have spent a lot of time on Stack Overflow trying to find out how to do this.
References:
"Updating ~/.lein/profiles.clj to {:repl {:dependencies [^:displace [org.clojure/clojure "1.9.0"]]}} does not seem to work. – Petrus Theron Jan 10 2018 at 9:05" How do you change Clojure version in Leiningen and LightTable?
"I asked technomancy on IRC just now. He said: "REPL's outside projects are hard coded to lein's version of clojure". – David J. Feb 24 '14 at 19:52" How to change Clojure or Lein's Clojure default version?
"this ^:displace trick will not work with tools.nrepl or clojure-complete." https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md
How to upgrade nrepl version of leiningen?
I think you may try to declare different profiles in your project.clj where each of them has its own Clojure version. For example:
:profiles
{;; :default [:base :system :user :provided :dev]
:server-jvm {:jvm-opts ^:replace ["-server"]}
:1.5 {:dependencies [[org.clojure/clojure "1.5.1"]]}
:1.6 {:dependencies [[org.clojure/clojure "1.6.0"]]}
:1.7 {:dependencies [[org.clojure/clojure "1.7.0"]]}
:1.8 {:dependencies [[org.clojure/clojure "1.8.0"]]}
:1.9 {:dependencies [[org.clojure/clojure "1.9.0"]]}}
Now that, when running any Lein command, specify a profile as follows:
lein with-profile 1.7 repl
The REPL session of Clojure 1.7 should start.
I grabbed that fragment from carmine sources. The official Lein profiles manual also has the same example.

Clojure Ring: How to determine if development server is running?

I have a project containing both Clojure & ClojureScript code. I would like to include unoptimized ClojureScript when I run my server via lein ring server and optimized ClojureScript otherwise. What is the idiomatic way to do this?
I am using:
[[bidi "1.19.0"]
[hiccup "1.0.5"]
[org.clojure/clojure "1.7.0-beta3"]
[org.clojure/clojurescript "0.0-3269"]]
[[lein-cljsbuild "1.0.4"]
[lein-ring "0.9.4"]]
My handler is just a simple one:
(def app (-> ["/" {:get {"" index-view}}]
(compile-route)
(make-handler)))
and this is my server directive:
:ring {:handler webapp.core/app}
I am looking for a way to be able to do this in my views:
(dev-server? request) ;; => true if it's a development server, otherwise false.
The idiomatic way to do this is to use leiningen profiles, using the :dev profile. You can then ensure inside the dev profile that your ClojureScript build is happening without optimization, cf. the leiningen cljsbuild compilation profiles.
If you want to be able to identify the devserver running, you can use environ -- include :env {:dev true} in your :dev profile and then in your code you can just call (env :dev). You might want to take a look at the reagent-template for inspiration.

Clojure ring server seems to be missing dependencies on slf4j

I've been trying to follow a number of tutorials on building a web app in Clojure, but I keep running into the same problem. To take the simplest case, I tried following this tutorial: http://drtom.ch/posts/2012-12-10/An_Introduction_to_Webprogramming_in_Clojure_-_Ring_and_Middleware/
When I get to the step that starts the server (run-jetty handler {:port 8383}), I get the following error:
NoSuchMethodError org.slf4j.helpers.MessageFormatter.arrayFormat(Ljava/lang/String;[Ljava/lang/Object;)Lorg/slf4j/helpers/FormattingTuple; org.eclipse.jetty.util.log.JettyAwareLogger.log (JettyAwareLogger.java:613)
I asked lien to show me the classpath, and sure enough, org.slf4j.helpers.MessageFormatter isn't in there anywhere.
I've run into this on pretty much every ring-based web tutorial I've tried, so either I've got something configured weird (I updated and reinstalled lein, blew away my ~/.m2 and rebuilt, etc), or something has changed in the myriad dependencies that get put together to make the classpath.
Any ideas what's going on here?
EDIT
I've got further information -- I created a VM in virtualbox, installed OpenJDK and lein, and created a project there. It worked fine. Since I had created it in a directory shared with the host, I then tried doing "lein ring server" in the same directory from the host, and it failed with the above error.
So I did "lein classpath" both in the vm and in the host and compared the results -- they're identical. I also checked that they're running the same build of the same JVM (OpenJDK 64-bit build 24.51-b03).
So, if they're running the same JVM with identical classpaths, what's left?
Can you try updating the dependencies like the following?
(defproject ..........
:dependencies [[org.clojure/clojure "1.5.1"]
[ring/ring-core "1.1.8"]
[ring/ring-jetty-adapter "1.1.8"]
[compojure "1.1.3"]]
:main quickstart.core
:min-lein-version "2.0.0"
:plugins [[lein-ring "0.8.10"]]
:ring {:handler quickstart.core/handler})
If you use the lein ring plugin as configured above, you can start the application like:
lein ring server